diff options
1294 files changed, 21397 insertions, 11576 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 1b0ee6397784..f9cc1259a375 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -348,6 +348,7 @@ aconfig_declarations { name: "android.location.flags-aconfig", package: "android.location.flags", container: "system", + exportable: true, srcs: [ "location/java/android/location/flags/*.aconfig", ], @@ -588,7 +589,6 @@ aconfig_declarations { java_aconfig_library { name: "android.view.inputmethod.flags-aconfig-java", aconfig_declarations: "android.view.inputmethod.flags-aconfig", - host_supported: true, defaults: ["framework-minus-apex-aconfig-java-defaults"], } diff --git a/core/api/current.txt b/core/api/current.txt index 1630d80346ce..fbc8eefdd945 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -46681,16 +46681,16 @@ package android.telephony { method public int getLastCauseCode(); method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); - method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus(); + method public int getNetworkValidationStatus(); method public int getState(); method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR; - field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_FAILURE = 4; // 0x4 - field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; // 0x2 - field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; // 0x1 - field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_SUCCESS = 3; // 0x3 - field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; // 0x0 + field public static final int NETWORK_VALIDATION_FAILURE = 4; // 0x4 + field public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; // 0x2 + field public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; // 0x1 + field public static final int NETWORK_VALIDATION_SUCCESS = 3; // 0x3 + field public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; // 0x0 } public final class RadioAccessSpecifier implements android.os.Parcelable { @@ -55423,6 +55423,7 @@ package android.view { method public void dispatchOnDraw(); method public void dispatchOnGlobalLayout(); method public boolean dispatchOnPreDraw(); + method @FlaggedApi("android.view.flags.enable_dispatch_on_scroll_changed") public void dispatchOnScrollChanged(); method public boolean isAlive(); method public void registerFrameCommitCallback(@NonNull Runnable); method @Deprecated public void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index cd7e434d30d9..35720fd17769 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3643,11 +3643,26 @@ package android.companion.virtual.sensor { method public int getDeviceId(); method @NonNull public String getName(); method public int getType(); + method @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") public void sendAdditionalInfo(@NonNull android.companion.virtual.sensor.VirtualSensorAdditionalInfo); method public void sendEvent(@NonNull android.companion.virtual.sensor.VirtualSensorEvent); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensor> CREATOR; } + @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") public final class VirtualSensorAdditionalInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getType(); + method @NonNull public java.util.List<float[]> getValues(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensorAdditionalInfo> CREATOR; + } + + public static final class VirtualSensorAdditionalInfo.Builder { + ctor public VirtualSensorAdditionalInfo.Builder(int); + method @NonNull public android.companion.virtual.sensor.VirtualSensorAdditionalInfo.Builder addValues(@NonNull float[]); + method @NonNull public android.companion.virtual.sensor.VirtualSensorAdditionalInfo build(); + } + public interface VirtualSensorCallback { method public void onConfigurationChanged(@NonNull android.companion.virtual.sensor.VirtualSensor, boolean, @NonNull java.time.Duration, @NonNull java.time.Duration); } @@ -3665,6 +3680,7 @@ package android.companion.virtual.sensor { method public float getResolution(); method public int getType(); method @Nullable public String getVendor(); + method @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") public boolean isAdditionalInfoSupported(); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") public boolean isWakeUpSensor(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensorConfig> CREATOR; @@ -3673,6 +3689,7 @@ package android.companion.virtual.sensor { public static final class VirtualSensorConfig.Builder { ctor public VirtualSensorConfig.Builder(@IntRange(from=1) int, @NonNull String); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig build(); + method @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setAdditionalInfoSupported(boolean); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setDirectChannelTypesSupported(int); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setHighestDirectReportRateLevel(int); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setMaxDelay(int); @@ -16443,7 +16460,7 @@ package android.telephony.data { method @Deprecated public int getMtu(); method public int getMtuV4(); method public int getMtuV6(); - method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus(); + method public int getNetworkValidationStatus(); method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); method public int getPduSessionId(); method public int getProtocolType(); @@ -16480,7 +16497,7 @@ package android.telephony.data { method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); - method @FlaggedApi("com.android.internal.telephony.flags.network_validation") @NonNull public android.telephony.data.DataCallResponse.Builder setNetworkValidationStatus(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setNetworkValidationStatus(int); method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); method @NonNull public android.telephony.data.DataCallResponse.Builder setPduSessionId(@IntRange(from=android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET, to=15) int); method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); @@ -16560,7 +16577,7 @@ package android.telephony.data { method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); method public final void notifyDataProfileUnthrottled(@NonNull android.telephony.data.DataProfile); method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback); - method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); + method public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback); method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback); method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback); @@ -16622,7 +16639,7 @@ package android.telephony.data { method public final int getSlotIndex(); method public void reportEmergencyDataNetworkPreferredTransportChanged(int); method public void reportThrottleStatusChanged(@NonNull java.util.List<android.telephony.data.ThrottleStatus>); - method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); + method public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>); } diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 4a07de0410ae..36308e5e75b0 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -423,15 +423,19 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim notifyListeners(AnimatorCaller.ON_CANCEL, false); callOnPlayingSet(Animator::cancel); mPlayingSet.clear(); - // If the end callback is pending, invoke the end callbacks of the animator nodes before - // ending this set. Pass notifyListeners=false because this endAnimation will do that. - if (consumePendingEndListeners(false /* notifyListeners */)) { - for (int i = mNodeMap.size() - 1; i >= 0; i--) { - mNodeMap.keyAt(i).consumePendingEndListeners(true /* notifyListeners */); - } + endAnimationAndNotifyEndListenersImmediately(); + } + } + + private void endAnimationAndNotifyEndListenersImmediately() { + // If the end callback is pending, invoke the end callbacks of the animator nodes before + // ending this set. Pass notifyListeners=false because endAnimation will do that. + if (consumePendingEndListeners(false /* notifyListeners */)) { + for (int i = mNodeMap.size() - 1; i >= 0; i--) { + mNodeMap.keyAt(i).consumePendingEndListeners(true /* notifyListeners */); } - endAnimation(); } + endAnimation(); } /** @@ -529,7 +533,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim } } } - endAnimation(); + endAnimationAndNotifyEndListenersImmediately(); } /** @@ -1455,8 +1459,6 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim private void endAnimation(boolean fromLastFrame) { final boolean postNotifyEndListener = sPostNotifyEndListenerEnabled && mListeners != null && fromLastFrame && mTotalDuration > 0; - mStarted = false; - mLastFrameTime = -1; mFirstFrame = -1; mLastEventId = -1; mPaused = false; @@ -1466,11 +1468,18 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim // No longer receive callbacks removeAnimationCallback(); + // If postNotifyEndListener is false (most cases), then it is the same as calling + // completeEndAnimation directly. notifyEndListenersFromEndAnimation(mReversing, postNotifyEndListener); } @Override void completeEndAnimation(boolean isReversing, String notifyListenerTraceName) { + // The mStarted and mLastFrameTime are reset here because isStarted() and isRunning() + // can be true before notifying the end listeners. When notifying the end listeners, + // isStarted() and isRunning() should be false. + mStarted = false; + mLastFrameTime = -1; super.completeEndAnimation(isReversing, notifyListenerTraceName); removeAnimationEndListener(); mSelfPulse = true; diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index fbcc73ea59e7..8d34090c8f60 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -1212,6 +1212,10 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio initAnimation(); } animateValue(shouldPlayBackward(mRepeatCount, mReversing) ? 0f : 1f); + if (mAnimationEndRequested) { + consumePendingEndListeners(true /* notifyListeners */); + return; + } endAnimation(); } @@ -1308,8 +1312,8 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio mLastFrameTime = -1; mFirstFrameTime = -1; mStartTime = -1; - mRunning = false; - mStarted = false; + // If postNotifyEndListener is false (most cases), then it is the same as calling + // completeEndAnimation directly. notifyEndListenersFromEndAnimation(mReversing, postNotifyEndListener); if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(), @@ -1319,6 +1323,11 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio @Override void completeEndAnimation(boolean isReversing, String notifyListenerTraceName) { + // The mRunning and mStarted are reset here because isStarted() and isRunning() + // can be true before notifying the end listeners. When notifying the end listeners, + // isStarted() and isRunning() should be false. + mRunning = false; + mStarted = false; super.completeEndAnimation(isReversing, notifyListenerTraceName); // mReversing needs to be reset *after* notifying the listeners for the end callbacks. mReversing = false; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 0a2b1eaaad6b..96b50960f0a2 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -7831,9 +7831,10 @@ public final class ActivityThread extends ClientTransactionHandler // Register callback to report native memory metrics post GC cleanup // Note: we do not report memory metrics of isolated processes unless - // their native allocations become more significant - if (!Process.isIsolated() && Flags.reportPostgcMemoryMetrics() && - com.android.libcore.readonly.Flags.postCleanupApis()) { + // their native allocations become more significant. Instrumentation is + // also excluded because the metrics from test cases are not meaningful. + if (!Process.isIsolated() && ii == null && Flags.reportPostgcMemoryMetrics() + && com.android.libcore.readonly.Flags.postCleanupApis()) { VMRuntime.addPostCleanupCallback(new Runnable() { @Override public void run() { MetricsLoggerWrapper.logPostGcMemorySnapshot(); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 1ed64f9416c0..bdecbaeb455d 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -200,6 +200,8 @@ public class ApplicationPackageManager extends PackageManager { @GuardedBy("mPackageMonitorCallbacks") private final ArraySet<IRemoteCallback> mPackageMonitorCallbacks = new ArraySet<>(); + private final boolean mUseSystemFeaturesCache; + UserManager getUserManager() { if (mUserManager == null) { mUserManager = UserManager.get(mContext); @@ -300,13 +302,23 @@ public class ApplicationPackageManager extends PackageManager { @Override public Intent getLaunchIntentForPackage(String packageName) { + return getLaunchIntentForPackage(packageName, false); + } + + @Override + @Nullable + public Intent getLaunchIntentForPackage(@NonNull String packageName, + boolean includeDirectBootUnaware) { + ResolveInfoFlags queryFlags = ResolveInfoFlags.of( + includeDirectBootUnaware ? MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE : 0); + // First see if the package has an INFO activity; the existence of // such an activity is implied to be the desired front-door for the // overall package (such as if it has multiple launcher entries). Intent intentToResolve = new Intent(Intent.ACTION_MAIN); intentToResolve.addCategory(Intent.CATEGORY_INFO); intentToResolve.setPackage(packageName); - List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); + List<ResolveInfo> ris = queryIntentActivities(intentToResolve, queryFlags); // Otherwise, try to find a main launcher activity. if (ris == null || ris.size() <= 0) { @@ -314,7 +326,7 @@ public class ApplicationPackageManager extends PackageManager { intentToResolve.removeCategory(Intent.CATEGORY_INFO); intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); intentToResolve.setPackage(packageName); - ris = queryIntentActivities(intentToResolve, 0); + ris = queryIntentActivities(intentToResolve, queryFlags); } if (ris == null || ris.size() <= 0) { return null; @@ -824,8 +836,7 @@ public class ApplicationPackageManager extends PackageManager { if (maybeHasSystemFeature != null) { return maybeHasSystemFeature; } - if (com.android.internal.os.Flags.applicationSharedMemoryEnabled() - && android.content.pm.Flags.cacheSdkSystemFeatures()) { + if (mUseSystemFeaturesCache) { maybeHasSystemFeature = SystemFeaturesCache.getInstance().maybeHasFeature(name, version); if (maybeHasSystemFeature != null) { @@ -2221,6 +2232,25 @@ public class ApplicationPackageManager extends PackageManager { protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) { mContext = context; mPM = pm; + mUseSystemFeaturesCache = isSystemFeaturesCacheEnabledAndAvailable(); + } + + private static boolean isSystemFeaturesCacheEnabledAndAvailable() { + if (!android.content.pm.Flags.cacheSdkSystemFeatures()) { + return false; + } + if (!com.android.internal.os.Flags.applicationSharedMemoryEnabled()) { + return false; + } + if (ActivityThread.isSystem() && !SystemFeaturesCache.hasInstance()) { + // There are a handful of utility "system" processes that are neither system_server nor + // bound as applications. For these processes, we don't have access to application + // shared memory or the dependent system features cache. + // TODO(b/400713460): Revisit this exception after deprecating these command-like + // system processes. + return false; + } + return true; } /** diff --git a/core/java/android/app/AutomaticZenRule.aidl b/core/java/android/app/AutomaticZenRule.aidl index feb21d657c6a..92f7d5235cf7 100644 --- a/core/java/android/app/AutomaticZenRule.aidl +++ b/core/java/android/app/AutomaticZenRule.aidl @@ -16,4 +16,6 @@ package android.app; -parcelable AutomaticZenRule;
\ No newline at end of file +parcelable AutomaticZenRule; + +parcelable AutomaticZenRule.AzrWithId;
\ No newline at end of file diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index fa977c93113a..1ce38ace75d8 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -228,7 +228,7 @@ public final class AutomaticZenRule implements Parcelable { public AutomaticZenRule(Parcel source) { enabled = source.readInt() == ENABLED; if (source.readInt() == ENABLED) { - name = getTrimmedString(source.readString()); + name = getTrimmedString(source.readString8()); } interruptionFilter = source.readInt(); conditionId = getTrimmedUri(source.readParcelable(null, android.net.Uri.class)); @@ -238,11 +238,11 @@ public final class AutomaticZenRule implements Parcelable { source.readParcelable(null, android.content.ComponentName.class)); creationTime = source.readLong(); mZenPolicy = source.readParcelable(null, ZenPolicy.class); - mPkg = source.readString(); + mPkg = source.readString8(); mDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); mAllowManualInvocation = source.readBoolean(); mIconResId = source.readInt(); - mTriggerDescription = getTrimmedString(source.readString(), MAX_DESC_LENGTH); + mTriggerDescription = getTrimmedString(source.readString8(), MAX_DESC_LENGTH); mType = source.readInt(); } @@ -514,7 +514,7 @@ public final class AutomaticZenRule implements Parcelable { dest.writeInt(enabled ? ENABLED : DISABLED); if (name != null) { dest.writeInt(1); - dest.writeString(name); + dest.writeString8(name); } else { dest.writeInt(0); } @@ -524,11 +524,11 @@ public final class AutomaticZenRule implements Parcelable { dest.writeParcelable(configurationActivity, 0); dest.writeLong(creationTime); dest.writeParcelable(mZenPolicy, 0); - dest.writeString(mPkg); + dest.writeString8(mPkg); dest.writeParcelable(mDeviceEffects, 0); dest.writeBoolean(mAllowManualInvocation); dest.writeInt(mIconResId); - dest.writeString(mTriggerDescription); + dest.writeString8(mTriggerDescription); dest.writeInt(mType); } @@ -843,4 +843,41 @@ public final class AutomaticZenRule implements Parcelable { return rule; } } + + /** @hide */ + public static final class AzrWithId implements Parcelable { + public final String mId; + public final AutomaticZenRule mRule; + + public AzrWithId(String id, AutomaticZenRule rule) { + mId = id; + mRule = rule; + } + + public static final Creator<AzrWithId> CREATOR = new Creator<>() { + @Override + public AzrWithId createFromParcel(Parcel in) { + return new AzrWithId( + in.readString8(), + in.readParcelable(AutomaticZenRule.class.getClassLoader(), + AutomaticZenRule.class)); + } + + @Override + public AzrWithId[] newArray(int size) { + return new AzrWithId[size]; + } + }; + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString8(mId); + dest.writeParcelable(mRule, flags); + } + + @Override + public int describeContents() { + return 0; + } + } } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 00df7246a300..1f0cd39a823c 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -224,7 +224,7 @@ interface INotificationManager void setNotificationPolicyAccessGrantedForUser(String pkg, int userId, boolean granted); ZenPolicy getDefaultZenPolicy(); AutomaticZenRule getAutomaticZenRule(String id); - Map<String, AutomaticZenRule> getAutomaticZenRules(); + ParceledListSlice getAutomaticZenRules(); String addAutomaticZenRule(in AutomaticZenRule automaticZenRule, String pkg, boolean fromUser); boolean updateAutomaticZenRule(String id, in AutomaticZenRule automaticZenRule, boolean fromUser); boolean removeAutomaticZenRule(String id, boolean fromUser); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index feaa98f644a0..7c293cb9cb3b 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6470,9 +6470,11 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.notification_material_reply_text_3, View.GONE); contentView.setTextViewText(R.id.notification_material_reply_text_3, null); - // This may get erased by bindSnoozeAction, or if we're showing the bubble icon - contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, - RemoteViews.MARGIN_BOTTOM, R.dimen.notification_content_margin); + if (!notificationsRedesignTemplates()) { + // This may get erased by bindSnoozeAction, or if we're showing the bubble icon + contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, + RemoteViews.MARGIN_BOTTOM, R.dimen.notification_content_margin); + } } private boolean bindSnoozeAction(RemoteViews contentView, StandardTemplateParams p) { @@ -6489,7 +6491,7 @@ public class Notification implements Parcelable final boolean snoozeEnabled = !hideSnoozeButton && mContext.getContentResolver() != null && isSnoozeSettingEnabled(); - if (snoozeEnabled) { + if (!notificationsRedesignTemplates() && snoozeEnabled) { contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, RemoteViews.MARGIN_BOTTOM, 0); } @@ -6569,44 +6571,18 @@ public class Notification implements Parcelable } boolean validRemoteInput = false; + // With the new design, the actions_container should always be visible to act as padding + // when there are no actions. We're making its child GONE instead. + int actionsContainerForVisibilityChange = notificationsRedesignTemplates() + ? R.id.actions_container_layout : R.id.actions_container; if (numActions > 0 && !p.mHideActions) { - contentView.setViewVisibility(R.id.actions_container, View.VISIBLE); + contentView.setViewVisibility(actionsContainerForVisibilityChange, View.VISIBLE); contentView.setViewVisibility(R.id.actions, View.VISIBLE); - contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, - RemoteViews.MARGIN_BOTTOM, 0); - if (notificationsRedesignTemplates()) { - // No need for additional space under smart replies/smart actions. - contentView.setViewLayoutMarginDimen(R.id.smart_reply_container, - RemoteViews.MARGIN_BOTTOM, 0); - if (emphasizedMode) { - // Emphasized actions look similar to smart replies, so let's use the same - // margins. - contentView.setViewLayoutMarginDimen(R.id.actions_container, - RemoteViews.MARGIN_TOP, - R.dimen.notification_2025_smart_reply_container_margin); - contentView.setViewLayoutMarginDimen(R.id.actions_container, - RemoteViews.MARGIN_BOTTOM, - R.dimen.notification_2025_smart_reply_container_margin); - } else { - contentView.setViewLayoutMarginDimen(R.id.actions_container, - RemoteViews.MARGIN_TOP, 0); - contentView.setViewLayoutMarginDimen(R.id.actions_container, - RemoteViews.MARGIN_BOTTOM, - R.dimen.notification_2025_action_list_margin_bottom); - } - } + updateMarginsForActions(contentView, emphasizedMode); validRemoteInput = populateActionsContainer(contentView, p, nonContextualActions, numActions, emphasizedMode); } else { - contentView.setViewVisibility(R.id.actions_container, View.GONE); - if (notificationsRedesignTemplates() && !snoozeEnabled) { - // Make sure smart replies & smart actions have enough space at the bottom - // (if present) when there are no actions. This should be set to 0 if we're - // showing the snooze or bubble buttons. - contentView.setViewLayoutMarginDimen(R.id.smart_reply_container, - RemoteViews.MARGIN_BOTTOM, - R.dimen.notification_2025_smart_reply_container_margin); - } + contentView.setViewVisibility(actionsContainerForVisibilityChange, View.GONE); } RemoteInputHistoryItem[] replyText = getParcelableArrayFromBundle( @@ -6652,6 +6628,30 @@ public class Notification implements Parcelable return contentView; } + private void updateMarginsForActions(RemoteViews contentView, boolean emphasizedMode) { + if (notificationsRedesignTemplates()) { + if (emphasizedMode) { + // Emphasized actions look similar to smart replies, so let's use the same + // margins. + contentView.setViewLayoutMarginDimen(R.id.actions_container, + RemoteViews.MARGIN_TOP, + R.dimen.notification_2025_smart_reply_container_margin); + contentView.setViewLayoutMarginDimen(R.id.actions_container, + RemoteViews.MARGIN_BOTTOM, + R.dimen.notification_2025_smart_reply_container_margin); + } else { + contentView.setViewLayoutMarginDimen(R.id.actions_container, + RemoteViews.MARGIN_TOP, 0); + contentView.setViewLayoutMarginDimen(R.id.actions_container, + RemoteViews.MARGIN_BOTTOM, + R.dimen.notification_2025_action_list_margin_bottom); + } + } else { + contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, + RemoteViews.MARGIN_BOTTOM, 0); + } + } + private boolean populateActionsContainer(RemoteViews contentView, StandardTemplateParams p, List<Action> nonContextualActions, int numActions, boolean emphasizedMode) { boolean validRemoteInput = false; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 050ef23b89e3..69e3ef9086d5 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1747,7 +1747,15 @@ public class NotificationManager { public Map<String, AutomaticZenRule> getAutomaticZenRules() { INotificationManager service = service(); try { - return service.getAutomaticZenRules(); + Map<String, AutomaticZenRule> result = new HashMap<>(); + ParceledListSlice<AutomaticZenRule.AzrWithId> parceledRules = + service.getAutomaticZenRules(); + if (parceledRules != null) { + for (AutomaticZenRule.AzrWithId rule : parceledRules.getList()) { + result.put(rule.mId, rule.mRule); + } + } + return result; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index c74bd1a092ee..c528db8f1809 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -224,7 +224,7 @@ import java.util.function.Consumer; * <li>A <i id="deviceowner">Device Owner</i>, which only ever exists on the * {@link UserManager#isSystemUser System User} or Main User, is * the most powerful type of Device Policy Controller and can affect policy across the device. - * <li>A <i id="profileowner">Profile Owner<i>, which can exist on any user, can + * <li>A <i id="profileowner">Profile Owner</i>, which can exist on any user, can * affect policy on the user it is on, and when it is running on * {@link UserManager#isProfile a profile} has * <a href="#profile-on-parent">limited</a> ability to affect policy on its parent. diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java index 7718d159896e..3c8b1a0482ad 100644 --- a/core/java/android/app/jank/JankDataProcessor.java +++ b/core/java/android/app/jank/JankDataProcessor.java @@ -366,7 +366,7 @@ public class JankDataProcessor { 30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900, 1000, Integer.MAX_VALUE }; - private final int[] mFrameOverrunBuckets = new int[sFrameOverrunHistogramBounds.length]; + private final int[] mFrameOverrunBuckets = new int[sFrameOverrunHistogramBounds.length - 1]; // Histogram of frame duration overruns encoded in predetermined buckets. public PendingJankStat() { @@ -511,7 +511,7 @@ public class JankDataProcessor { if (overrunTime <= 1000) { return (overrunTime - 200) / 100 + 43; } - return sFrameOverrunHistogramBounds.length - 1; + return mFrameOverrunBuckets.length - 1; } } diff --git a/core/java/android/app/jank/TEST_MAPPING b/core/java/android/app/jank/TEST_MAPPING new file mode 100644 index 000000000000..271eb4332f79 --- /dev/null +++ b/core/java/android/app/jank/TEST_MAPPING @@ -0,0 +1,10 @@ +{ + "postsubmit": [ + { + "name": "CoreAppJankTestCases" + }, + { + "name": "CtsAppJankTestCases" + } + ] +}
\ No newline at end of file diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig index 5891bddfbbe6..6f0eafe487af 100644 --- a/core/java/android/app/notification.aconfig +++ b/core/java/android/app/notification.aconfig @@ -269,7 +269,7 @@ flag { namespace: "systemui" description: "enables metrics when redacting notifications on the lockscreen" bug: "343631648" - metadata { + metadata { purpose: PURPOSE_BUGFIX } } @@ -279,7 +279,16 @@ flag { namespace: "systemui" description: "enables user expanding the public view of a notification" bug: "398853084" - metadata { + metadata { + purpose: PURPOSE_BUGFIX + } + } +flag { + name: "notif_entry_creation_time_use_elapsed_realtime" + namespace: "systemui" + description: "makes the notification entry expect its creation time to be elapsedRealtime, not uptimeMillis" + bug: "343631648" + metadata { purpose: PURPOSE_BUGFIX } } diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java index a13af7f1ddcd..d7d6262599da 100644 --- a/core/java/android/app/wallpaper/WallpaperDescription.java +++ b/core/java/android/app/wallpaper/WallpaperDescription.java @@ -168,6 +168,12 @@ public final class WallpaperDescription implements Parcelable { return mSampleSize; } + @Override + public String toString() { + String component = (mComponent != null) ? mComponent.toString() : "{null}"; + return component + ":" + mId; + } + ////// Comparison overrides @Override diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl index f8ac27de1754..db77adeb5a3d 100644 --- a/core/java/android/companion/virtual/IVirtualDevice.aidl +++ b/core/java/android/companion/virtual/IVirtualDevice.aidl @@ -24,6 +24,7 @@ import android.companion.virtual.IVirtualDeviceSoundEffectListener; import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; import android.companion.virtual.sensor.VirtualSensor; +import android.companion.virtual.sensor.VirtualSensorAdditionalInfo; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorEvent; import android.companion.virtual.camera.VirtualCameraConfig; @@ -251,6 +252,11 @@ interface IVirtualDevice { boolean sendSensorEvent(IBinder token, in VirtualSensorEvent event); /** + * Sends additional information about the virtual sensor corresponding to the given token. + */ + boolean sendSensorAdditionalInfo(IBinder token, in VirtualSensorAdditionalInfo info); + + /** * Launches a pending intent on the given display that is owned by this virtual device. */ void launchPendingIntent(int displayId, in PendingIntent pendingIntent, diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig index 4fb3982c3754..615a6dffdf99 100644 --- a/core/java/android/companion/virtual/flags/flags.aconfig +++ b/core/java/android/companion/virtual/flags/flags.aconfig @@ -158,3 +158,11 @@ flag { bug: "370720522" is_exported: true } + +flag { + name: "virtual_sensor_additional_info" + namespace: "virtual_devices" + description: "API for injecting SensorAdditionalInfo for VirtualSensor" + bug: "393517834" + is_exported: true +} diff --git a/core/java/android/companion/virtual/sensor/VirtualSensor.java b/core/java/android/companion/virtual/sensor/VirtualSensor.java index 934a1a8ffcbd..8d4acfcb30d7 100644 --- a/core/java/android/companion/virtual/sensor/VirtualSensor.java +++ b/core/java/android/companion/virtual/sensor/VirtualSensor.java @@ -16,12 +16,15 @@ package android.companion.virtual.sensor; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.TestApi; import android.companion.virtual.IVirtualDevice; +import android.companion.virtualdevice.flags.Flags; import android.hardware.Sensor; +import android.hardware.SensorAdditionalInfo; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -37,20 +40,33 @@ import android.os.RemoteException; */ @SystemApi public final class VirtualSensor implements Parcelable { + private final int mHandle; private final int mType; private final String mName; + private final int mFlags; private final IVirtualDevice mVirtualDevice; private final IBinder mToken; + // Only one additional info frame set at a time. + private final Object mAdditionalInfoLock = new Object(); /** * @hide */ public VirtualSensor(int handle, int type, String name, IVirtualDevice virtualDevice, IBinder token) { + this(handle, type, name, /*flags=*/0, virtualDevice, token); + } + + /** + * @hide + */ + public VirtualSensor(int handle, int type, String name, int flags, IVirtualDevice virtualDevice, + IBinder token) { mHandle = handle; mType = type; mName = name; + mFlags = flags; mVirtualDevice = virtualDevice; mToken = token; } @@ -61,13 +77,14 @@ public final class VirtualSensor implements Parcelable { @SuppressLint("UnflaggedApi") // @TestApi without associated feature. @TestApi public VirtualSensor(int handle, int type, @NonNull String name) { - this(handle, type, name, /*virtualDevice=*/null, /*token=*/null); + this(handle, type, name, /*flags=*/0, /*virtualDevice=*/null, /*token=*/null); } private VirtualSensor(Parcel parcel) { mHandle = parcel.readInt(); mType = parcel.readInt(); mName = parcel.readString8(); + mFlags = parcel.readInt(); mVirtualDevice = IVirtualDevice.Stub.asInterface(parcel.readStrongBinder()); mToken = parcel.readStrongBinder(); } @@ -123,6 +140,7 @@ public final class VirtualSensor implements Parcelable { parcel.writeInt(mHandle); parcel.writeInt(mType); parcel.writeString8(mName); + parcel.writeInt(mFlags); parcel.writeStrongBinder(mVirtualDevice.asBinder()); parcel.writeStrongBinder(mToken); } @@ -143,6 +161,33 @@ public final class VirtualSensor implements Parcelable { } } + /** + * Send additional information about the sensor to the system. + * + * @param info the additional sensor information to send. + * @throws UnsupportedOperationException if the sensor does not support sending additional info. + * @see Sensor#isAdditionalInfoSupported() + * @see VirtualSensorConfig.Builder#setAdditionalInfoSupported(boolean) + * @see SensorAdditionalInfo + * @see VirtualSensorAdditionalInfo + */ + @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO) + public void sendAdditionalInfo(@NonNull VirtualSensorAdditionalInfo info) { + if (!Flags.virtualSensorAdditionalInfo()) { + return; + } + if ((mFlags & VirtualSensorConfig.ADDITIONAL_INFO_MASK) == 0) { + throw new UnsupportedOperationException("Sensor additional info not supported."); + } + try { + synchronized (mAdditionalInfoLock) { + mVirtualDevice.sendSensorAdditionalInfo(mToken, info); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + @NonNull public static final Parcelable.Creator<VirtualSensor> CREATOR = new Parcelable.Creator<VirtualSensor>() { diff --git a/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.aidl b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.aidl new file mode 100644 index 000000000000..7267be88ca75 --- /dev/null +++ b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2025 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.companion.virtual.sensor; + +parcelable VirtualSensorAdditionalInfo;
\ No newline at end of file diff --git a/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.java b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.java new file mode 100644 index 000000000000..a4fca507b1d5 --- /dev/null +++ b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2025 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.companion.virtual.sensor; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.companion.virtualdevice.flags.Flags; +import android.hardware.SensorAdditionalInfo; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; + +/** + * An additional information frame for a {@link VirtualSensor}, which is reported through listener + * callback {@link android.hardware.SensorEventCallback#onSensorAdditionalInfo}. + * + * @see SensorAdditionalInfo + * @see VirtualSensorConfig.Builder#setAdditionalInfoSupported(boolean) + * @hide + */ +@FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO) +@SystemApi +public final class VirtualSensorAdditionalInfo implements Parcelable { + + private final int mType; + @NonNull + private final List<float[]> mValues; + + /** @hide */ + @IntDef(prefix = "TYPE_", value = { + SensorAdditionalInfo.TYPE_UNTRACKED_DELAY, + SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE, + SensorAdditionalInfo.TYPE_VEC3_CALIBRATION, + SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT, + SensorAdditionalInfo.TYPE_SAMPLING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Type {} + + private VirtualSensorAdditionalInfo(int type, @NonNull List<float[]> values) { + mType = type; + mValues = values; + } + + private VirtualSensorAdditionalInfo(@NonNull Parcel parcel) { + mType = parcel.readInt(); + final int valuesLength = parcel.readInt(); + mValues = new ArrayList<>(valuesLength); + for (int i = 0; i < valuesLength; ++i) { + mValues.add(parcel.createFloatArray()); + } + } + + @Override + public void writeToParcel(@NonNull Parcel parcel, int parcelableFlags) { + parcel.writeInt(mType); + parcel.writeInt(mValues.size()); + for (int i = 0; i < mValues.size(); ++i) { + parcel.writeFloatArray(mValues.get(i)); + } + } + + @Override + public int describeContents() { + return 0; + } + + /** + * Returns the type of this information frame. + * + * @see SensorAdditionalInfo#type + */ + public int getType() { + return mType; + } + + /** + * Returns the float values of this information frame, if any. + * + * @see SensorAdditionalInfo#floatValues + */ + @NonNull + public List<float[]> getValues() { + return mValues; + } + + /** + * Builder for {@link VirtualSensorAdditionalInfo}. + */ + public static final class Builder { + + @VirtualSensorAdditionalInfo.Type + private final int mType; + @NonNull + private final ArrayList<float[]> mValues = new ArrayList<>(); + + /** + * Creates a new builder. + * + * @param type type of this additional info frame. + * @see SensorAdditionalInfo + */ + public Builder(@VirtualSensorAdditionalInfo.Type int type) { + switch (type) { + case SensorAdditionalInfo.TYPE_UNTRACKED_DELAY: + case SensorAdditionalInfo.TYPE_SAMPLING: + case SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE: + case SensorAdditionalInfo.TYPE_VEC3_CALIBRATION: + case SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT: + break; + default: + throw new IllegalArgumentException("Unsupported type " + type); + } + mType = type; + } + + /** + * Additional info payload data represented in float values. Depending on the type of + * information, this may be null. + * + * @see SensorAdditionalInfo#floatValues + */ + @NonNull + public Builder addValues(@NonNull float[] values) { + if (values.length > 14) { + throw new IllegalArgumentException("Maximum payload value size is 14."); + } + if (mValues.isEmpty()) { + switch (mType) { + case SensorAdditionalInfo.TYPE_UNTRACKED_DELAY: + case SensorAdditionalInfo.TYPE_SAMPLING: + assertValuesLength(values, 2); + break; + case SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE: + assertValuesLength(values, 1); + break; + case SensorAdditionalInfo.TYPE_VEC3_CALIBRATION: + case SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT: + assertValuesLength(values, 11); + break; + } + } else if (values.length != mValues.getFirst().length) { + throw new IllegalArgumentException("All payload values must have the same length"); + } + + mValues.add(values); + return this; + } + + private void assertValuesLength(float[] values, int expected) { + if (values.length != expected) { + throw new IllegalArgumentException( + "Payload values must have size " + expected + " for type " + mType); + } + } + + /** + * Creates a new {@link VirtualSensorAdditionalInfo}. + * + * @throws IllegalArgumentException if the payload doesn't match the expectation for the + * given type, as documented in {@link SensorAdditionalInfo}. + */ + @NonNull + public VirtualSensorAdditionalInfo build() { + if (mValues.isEmpty()) { + throw new IllegalArgumentException("Payload is required"); + } + return new VirtualSensorAdditionalInfo(mType, mValues); + } + } + + public static final @NonNull Creator<VirtualSensorAdditionalInfo> CREATOR = + new Creator<>() { + public VirtualSensorAdditionalInfo createFromParcel(Parcel source) { + return new VirtualSensorAdditionalInfo(source); + } + + public VirtualSensorAdditionalInfo[] newArray(int size) { + return new VirtualSensorAdditionalInfo[size]; + } + }; +} diff --git a/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java b/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java index 68bc9bce28d2..be8974ec29ad 100644 --- a/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java +++ b/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java @@ -59,10 +59,14 @@ public final class VirtualSensorConfig implements Parcelable { private static final int REPORTING_MODE_MASK = 0xE; private static final int REPORTING_MODE_SHIFT = 1; + // Mask for indication bit of sensor additional information support, bit 6. + static final int ADDITIONAL_INFO_MASK = 0x40; + // Mask for direct mode highest rate level, bit 7, 8, 9. private static final int DIRECT_REPORT_MASK = 0x380; private static final int DIRECT_REPORT_SHIFT = 7; + // Mask for supported direct channel, bit 10, 11 private static final int DIRECT_CHANNEL_SHIFT = 10; @@ -253,6 +257,18 @@ public final class VirtualSensorConfig implements Parcelable { } /** + * Returns whether the sensor supports additional information. + * + * @see Builder#setAdditionalInfoSupported(boolean) + * @see Sensor#isAdditionalInfoSupported() + * @see android.hardware.SensorAdditionalInfo + */ + @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO) + public boolean isAdditionalInfoSupported() { + return (mFlags & ADDITIONAL_INFO_MASK) > 0; + } + + /** * Returns the reporting mode of this sensor. * * @see Builder#setReportingMode(int) @@ -450,6 +466,25 @@ public final class VirtualSensorConfig implements Parcelable { } /** + * Sets whether this sensor supports sensor additional information. + * + * @see Sensor#isAdditionalInfoSupported() + * @see android.hardware.SensorAdditionalInfo + * @see VirtualSensorAdditionalInfo + */ + @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO) + @NonNull + public VirtualSensorConfig.Builder setAdditionalInfoSupported( + boolean additionalInfoSupported) { + if (additionalInfoSupported) { + mFlags |= ADDITIONAL_INFO_MASK; + } else { + mFlags &= ~ADDITIONAL_INFO_MASK; + } + return this; + } + + /** * Sets the reporting mode of this sensor. * * @throws IllegalArgumentException if the reporting mode is not one of diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 49fd6344270e..53966b8af533 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -5964,7 +5964,39 @@ public abstract class PackageManager { * * @see #getLaunchIntentSenderForPackage(String) */ - public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName); + public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName); + + /** + * Returns a "good" intent to launch a front-door activity in a package. + * This is used, for example, to implement an "open" button when browsing + * through packages. The current implementation looks first for a main + * activity in the category {@link Intent#CATEGORY_INFO}, and next for a + * main activity in the category {@link Intent#CATEGORY_LAUNCHER}. Returns + * <code>null</code> if neither are found. + * + * <p>Consider using {@link #getLaunchIntentSenderForPackage(String)} if + * the caller is not allowed to query for the <code>packageName</code>. + * + * @param packageName The name of the package to inspect. + * @param includeDirectBootUnaware When {@code true}, activities that are direct-boot-unaware + * will be considered even if the device hasn't been unlocked (i.e. querying will be done + * with {@code MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE}). + * + * @return A fully-qualified {@link Intent} that can be used to launch the + * main activity in the package. Returns <code>null</code> if the package + * does not contain such an activity, or if <em>packageName</em> is not + * recognized. + * + * @see #getLaunchIntentSenderForPackage(String) + * + * @hide + */ + public @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName, + boolean includeDirectBootUnaware) { + throw new UnsupportedOperationException( + "getLaunchIntentForPackage(packageName, includeDirectBootUnaware) not implemented" + + " in subclass"); + } /** * Return a "good" intent to launch a front-door Leanback activity in a diff --git a/core/java/android/content/pm/SystemFeaturesCache.java b/core/java/android/content/pm/SystemFeaturesCache.java index b3d70fa8bfaf..57dd1e6f4d3b 100644 --- a/core/java/android/content/pm/SystemFeaturesCache.java +++ b/core/java/android/content/pm/SystemFeaturesCache.java @@ -74,6 +74,11 @@ public final class SystemFeaturesCache { return instance; } + /** Checks for existence of the process-global instance. */ + public static boolean hasInstance() { + return sInstance != null; + } + /** Clears the process-global cache instance for testing. */ @VisibleForTesting public static void clearInstance() { diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING index 23f1ff8926df..92ae15a296b7 100644 --- a/core/java/android/content/pm/TEST_MAPPING +++ b/core/java/android/content/pm/TEST_MAPPING @@ -136,6 +136,28 @@ ] }, { + "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { + "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { "name": "CtsPackageInstallerCUJMultiUsersTestCases", "options":[ { @@ -261,6 +283,28 @@ ] }, { + "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { + "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { "name": "CtsPackageInstallerCUJMultiUsersTestCases", "options":[ { diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig index 7f57f5dbf0ab..3411a4897e83 100644 --- a/core/java/android/content/pm/multiuser.aconfig +++ b/core/java/android/content/pm/multiuser.aconfig @@ -636,3 +636,13 @@ flag { description: "Enables support for new supervising user type" bug: "389712089" } + +flag { + name: "use_unified_resources" + namespace: "multiuser" + description: "Use same resources" + bug: "392972139" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java index fdde2057a1a0..de3bafb4bb56 100644 --- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java +++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java @@ -75,7 +75,6 @@ public class MarshalQueryableParcelable<T extends Parcelable> } Parcel parcel = Parcel.obtain(); - byte[] parcelContents; try { value.writeToParcel(parcel, /*flags*/0); @@ -85,17 +84,15 @@ public class MarshalQueryableParcelable<T extends Parcelable> "Parcelable " + value + " must not have file descriptors"); } - parcelContents = parcel.marshall(); + final int position = buffer.position(); + parcel.marshall(buffer); + if (buffer.position() == position) { + throw new AssertionError("No data marshaled for " + value); + } } finally { parcel.recycle(); } - - if (parcelContents.length == 0) { - throw new AssertionError("No data marshaled for " + value); - } - - buffer.put(parcelContents); } @Override diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java index 4ed0fc056e7d..c3c8c3d63bec 100644 --- a/core/java/android/hardware/display/DisplayTopology.java +++ b/core/java/android/hardware/display/DisplayTopology.java @@ -600,8 +600,7 @@ public final class DisplayTopology implements Parcelable { private void addDisplay(int displayId, float width, float height, boolean shouldLog) { if (findDisplay(displayId, mRoot) != null) { - throw new IllegalArgumentException( - "DisplayTopology: attempting to add a display that already exists"); + return; } if (mRoot == null) { mRoot = new TreeNode(displayId, width, height, POSITION_LEFT, /* offset= */ 0); diff --git a/core/java/android/hardware/serial/OWNERS b/core/java/android/hardware/serial/OWNERS index bc2c66ae7ecd..13f6774a4264 100644 --- a/core/java/android/hardware/serial/OWNERS +++ b/core/java/android/hardware/serial/OWNERS @@ -3,4 +3,5 @@ mjel@google.com chominskib@google.com wzwonarz@google.com gstepniewski@google.com -xutan@google.com
\ No newline at end of file +xutan@google.com +ovn@google.com diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 894b068b1528..2e7bc6d9b9f7 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -428,6 +428,9 @@ public class InputMethodService extends AbstractInputMethodService { */ @AnyThread public static boolean canImeRenderGesturalNavButtons() { + if (Flags.disallowDisablingImeNavigationBar()) { + return true; + } return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true); } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 49d3f06eb80f..6cb49b3ea166 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -52,6 +52,8 @@ import com.android.internal.util.ArrayUtils; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; +import java.nio.BufferOverflowException; +import java.nio.ReadOnlyBufferException; import libcore.util.SneakyThrow; import java.io.ByteArrayInputStream; @@ -62,6 +64,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.nio.ByteBuffer; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Array; @@ -457,8 +460,15 @@ public final class Parcel { private static native void nativeDestroy(long nativePtr); private static native byte[] nativeMarshall(long nativePtr); + private static native int nativeMarshallArray( + long nativePtr, byte[] data, int offset, int length); + private static native int nativeMarshallBuffer( + long nativePtr, ByteBuffer buffer, int offset, int length); private static native void nativeUnmarshall( long nativePtr, byte[] data, int offset, int length); + private static native void nativeUnmarshallBuffer( + long nativePtr, ByteBuffer buffer, int offset, int length); + private static native int nativeCompareData(long thisNativePtr, long otherNativePtr); private static native boolean nativeCompareDataInRange( long ptrA, int offsetA, long ptrB, int offsetB, int length); @@ -814,12 +824,80 @@ public final class Parcel { } /** + * Writes the raw bytes of the parcel to a buffer. + * + * <p class="note">The data you retrieve here <strong>must not</strong> + * be placed in any kind of persistent storage (on local disk, across + * a network, etc). For that, you should use standard serialization + * or another kind of general serialization mechanism. The Parcel + * marshalled representation is highly optimized for local IPC, and as + * such does not attempt to maintain compatibility with data created + * in different versions of the platform. + * + * @param buffer The ByteBuffer to write the data to. + * @throws ReadOnlyBufferException if the buffer is read-only. + * @throws BufferOverflowException if the buffer is too small. + * + * @hide + */ + public final void marshall(@NonNull ByteBuffer buffer) { + if (buffer == null) { + throw new NullPointerException(); + } + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + + final int position = buffer.position(); + final int remaining = buffer.remaining(); + + int marshalledSize = 0; + if (buffer.isDirect()) { + marshalledSize = nativeMarshallBuffer(mNativePtr, buffer, position, remaining); + } else if (buffer.hasArray()) { + marshalledSize = nativeMarshallArray( + mNativePtr, buffer.array(), buffer.arrayOffset() + position, remaining); + } else { + throw new IllegalArgumentException(); + } + + buffer.position(position + marshalledSize); + } + + /** * Fills the raw bytes of this Parcel with the supplied data. */ public final void unmarshall(@NonNull byte[] data, int offset, int length) { nativeUnmarshall(mNativePtr, data, offset, length); } + /** + * Fills the raw bytes of this Parcel with data from the supplied buffer. + * + * @param buffer will read buffer.remaining() bytes from the buffer. + * + * @hide + */ + public final void unmarshall(@NonNull ByteBuffer buffer) { + if (buffer == null) { + throw new NullPointerException(); + } + + final int position = buffer.position(); + final int remaining = buffer.remaining(); + + if (buffer.isDirect()) { + nativeUnmarshallBuffer(mNativePtr, buffer, position, remaining); + } else if (buffer.hasArray()) { + nativeUnmarshall( + mNativePtr, buffer.array(), buffer.arrayOffset() + position, remaining); + } else { + throw new IllegalArgumentException(); + } + + buffer.position(position + remaining); + } + public final void appendFrom(Parcel parcel, int offset, int length) { nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length); } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 0433c76fbbf4..17033d1143c6 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -1907,9 +1907,9 @@ public final class PermissionManager { @Context.PermissionRequestState public int getPermissionRequestState(@NonNull String packageName, @NonNull String permission, int deviceId) { - int actualDeviceId = resolveDeviceIdForPermissionCheck(mContext, deviceId, permission); + int resolvedDeviceId = resolveDeviceIdForPermissionCheck(mContext, deviceId, permission); return sPermissionRequestStateCache.query( - new PermissionRequestStateQuery(packageName, permission, actualDeviceId)); + new PermissionRequestStateQuery(packageName, permission, resolvedDeviceId)); } /** @@ -2036,8 +2036,8 @@ public final class PermissionManager { */ public int checkPackageNamePermission(String permName, String pkgName, int deviceId, @UserIdInt int userId) { - int actualDeviceId = resolveDeviceIdForPermissionCheck(mContext, deviceId, permName); - String persistentDeviceId = getPersistentDeviceId(actualDeviceId); + int resolvedDeviceId = resolveDeviceIdForPermissionCheck(mContext, deviceId, permName); + String persistentDeviceId = getPersistentDeviceId(resolvedDeviceId); return sPackageNamePermissionCache.query( new PackageNamePermissionQuery(permName, pkgName, persistentDeviceId, userId)); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 85f38c984f5c..b7e296228e45 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -19815,6 +19815,14 @@ public final class Settings { public static final String REPAIR_MODE_ACTIVE = "repair_mode_active"; /** + * Whether the notification manager service should redact notifications that contain otps + * from untrusted listeners. Defaults to 1/true. + * @hide + */ + public static final String REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS = + "redact_otp_notifications_from_untrusted_listeners"; + + /** * Settings migrated from Wear OS settings provider. * @hide */ diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java index 0b2239aa42b2..62b2bcf32442 100644 --- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java +++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java @@ -124,6 +124,18 @@ public final class AdvancedProtectionManager { @Retention(RetentionPolicy.SOURCE) public @interface FeatureId {} + /** @hide */ + public static String featureIdToString(@FeatureId int featureId) { + return switch(featureId) { + case FEATURE_ID_DISALLOW_CELLULAR_2G -> "DISALLOW_CELLULAR_2G"; + case FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES -> "DISALLOW_INSTALL_UNKNOWN_SOURCES"; + case FEATURE_ID_DISALLOW_USB -> "DISALLOW_USB"; + case FEATURE_ID_DISALLOW_WEP -> "DISALLOW_WEP"; + case FEATURE_ID_ENABLE_MTE -> "ENABLE_MTE"; + default -> "UNKNOWN"; + }; + } + private static final Set<Integer> ALL_FEATURE_IDS = Set.of( FEATURE_ID_DISALLOW_CELLULAR_2G, FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES, @@ -147,7 +159,7 @@ public final class AdvancedProtectionManager { "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG"; /** - * A string extra used with {@link #createSupportIntent} to identify the feature that needs to + * An int extra used with {@link #createSupportIntent} to identify the feature that needs to * show a support dialog explaining it was disabled by advanced protection. * * @hide */ @@ -156,7 +168,7 @@ public final class AdvancedProtectionManager { "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE"; /** - * A string extra used with {@link #createSupportIntent} to identify the type of the action that + * An int extra used with {@link #createSupportIntent} to identify the type of the action that * needs to be explained in the support dialog. * * @hide */ @@ -194,6 +206,16 @@ public final class AdvancedProtectionManager { @Retention(RetentionPolicy.SOURCE) public @interface SupportDialogType {} + /** @hide */ + public static String supportDialogTypeToString(@SupportDialogType int type) { + return switch(type) { + case SUPPORT_DIALOG_TYPE_UNKNOWN -> "UNKNOWN"; + case SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION -> "BLOCKED_INTERACTION"; + case SUPPORT_DIALOG_TYPE_DISABLED_SETTING -> "DISABLED_SETTING"; + default -> "UNKNOWN"; + }; + } + private static final Set<Integer> ALL_SUPPORT_DIALOG_TYPES = Set.of( SUPPORT_DIALOG_TYPE_UNKNOWN, SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION, @@ -372,6 +394,17 @@ public final class AdvancedProtectionManager { return createSupportIntent(featureId, type); } + /** @hide */ + @RequiresPermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) + public void logDialogShown(@FeatureId int featureId, @SupportDialogType int type, + boolean learnMoreClicked) { + try { + mService.logDialogShown(featureId, type, learnMoreClicked); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * A callback class for monitoring changes to Advanced Protection state * diff --git a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl index 1939f829c700..0fc0fbea2989 100644 --- a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl +++ b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl @@ -35,4 +35,6 @@ interface IAdvancedProtectionService { void setAdvancedProtectionEnabled(boolean enabled); @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE") List<AdvancedProtectionFeature> getAdvancedProtectionFeatures(); + @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE") + void logDialogShown(int featureId, int type, boolean learnMoreClicked); }
\ No newline at end of file diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 7013f7d705f8..9fd4618bc5da 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -83,13 +83,6 @@ flag { } flag { - name: "report_primary_auth_attempts" - namespace: "biometrics" - description: "Report primary auth attempts from LockSettingsService" - bug: "285053096" -} - -flag { name: "dump_attestation_verifications" namespace: "hardware_backed_security" description: "Add a dump capability for attestation_verification service" diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java index 7660ed96d30e..815444d195c9 100644 --- a/core/java/android/service/notification/NotificationRankingUpdate.java +++ b/core/java/android/service/notification/NotificationRankingUpdate.java @@ -219,7 +219,7 @@ public class NotificationRankingUpdate implements Parcelable { // Gets a read/write buffer mapping the entire shared memory region. buffer = mRankingMapFd.mapReadWrite(); // Puts the ranking map into the shared memory region buffer. - buffer.put(mapParcel.marshall(), 0, mapSize); + mapParcel.marshall(buffer); // Protects the region from being written to, by setting it to be read-only. mRankingMapFd.setProtect(OsConstants.PROT_READ); // Puts the SharedMemory object in the parcel. diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 4cbd5beb3a8c..fce2df185461 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -62,6 +62,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.net.Uri; import android.os.Build; @@ -460,14 +461,21 @@ public class ZenModeConfig implements Parcelable { } private static void readRulesFromParcel(ArrayMap<String, ZenRule> ruleMap, Parcel source) { - final int len = source.readInt(); + int len = source.readInt(); if (len > 0) { final String[] ids = new String[len]; - final ZenRule[] rules = new ZenRule[len]; - source.readStringArray(ids); - source.readTypedArray(rules, ZenRule.CREATOR); + source.readString8Array(ids); + ParceledListSlice<?> parceledRules = source.readParcelable( + ZenRule.class.getClassLoader(), ParceledListSlice.class); + List<?> rules = parceledRules != null ? parceledRules.getList() : new ArrayList<>(); + if (rules.size() != len) { + Slog.wtf(TAG, String.format( + "Unexpected parceled rules count (%s != %s), throwing them out", + rules.size(), len)); + len = 0; + } for (int i = 0; i < len; i++) { - ruleMap.put(ids[i], rules[i]); + ruleMap.put(ids[i], (ZenRule) rules.get(i)); } } } @@ -485,8 +493,8 @@ public class ZenModeConfig implements Parcelable { } dest.writeInt(user); dest.writeParcelable(manualRule, 0); - writeRulesToParcel(automaticRules, dest); - writeRulesToParcel(deletedRules, dest); + writeRulesToParcel(automaticRules, dest, flags); + writeRulesToParcel(deletedRules, dest, flags); if (!Flags.modesUi()) { dest.writeInt(allowAlarms ? 1 : 0); dest.writeInt(allowMedia ? 1 : 0); @@ -501,18 +509,19 @@ public class ZenModeConfig implements Parcelable { } } - private static void writeRulesToParcel(ArrayMap<String, ZenRule> ruleMap, Parcel dest) { + private static void writeRulesToParcel(ArrayMap<String, ZenRule> ruleMap, Parcel dest, + int flags) { if (!ruleMap.isEmpty()) { final int len = ruleMap.size(); final String[] ids = new String[len]; - final ZenRule[] rules = new ZenRule[len]; + final ArrayList<ZenRule> rules = new ArrayList<>(); for (int i = 0; i < len; i++) { ids[i] = ruleMap.keyAt(i); - rules[i] = ruleMap.valueAt(i); + rules.add(ruleMap.valueAt(i)); } dest.writeInt(len); - dest.writeStringArray(ids); - dest.writeTypedArray(rules, 0); + dest.writeString8Array(ids); + dest.writeParcelable(new ParceledListSlice<>(rules), flags); } else { dest.writeInt(0); } @@ -2636,7 +2645,7 @@ public class ZenModeConfig implements Parcelable { enabled = source.readInt() == 1; snoozing = source.readInt() == 1; if (source.readInt() == 1) { - name = source.readString(); + name = source.readString8(); } zenMode = source.readInt(); conditionId = source.readParcelable(null, android.net.Uri.class); @@ -2644,18 +2653,18 @@ public class ZenModeConfig implements Parcelable { component = source.readParcelable(null, android.content.ComponentName.class); configurationActivity = source.readParcelable(null, android.content.ComponentName.class); if (source.readInt() == 1) { - id = source.readString(); + id = source.readString8(); } creationTime = source.readLong(); if (source.readInt() == 1) { - enabler = source.readString(); + enabler = source.readString8(); } zenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class); zenDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); - pkg = source.readString(); + pkg = source.readString8(); allowManualInvocation = source.readBoolean(); - iconResName = source.readString(); - triggerDescription = source.readString(); + iconResName = source.readString8(); + triggerDescription = source.readString8(); type = source.readInt(); userModifiedFields = source.readInt(); zenPolicyUserModifiedFields = source.readInt(); @@ -2703,7 +2712,7 @@ public class ZenModeConfig implements Parcelable { dest.writeInt(snoozing ? 1 : 0); if (name != null) { dest.writeInt(1); - dest.writeString(name); + dest.writeString8(name); } else { dest.writeInt(0); } @@ -2714,23 +2723,23 @@ public class ZenModeConfig implements Parcelable { dest.writeParcelable(configurationActivity, 0); if (id != null) { dest.writeInt(1); - dest.writeString(id); + dest.writeString8(id); } else { dest.writeInt(0); } dest.writeLong(creationTime); if (enabler != null) { dest.writeInt(1); - dest.writeString(enabler); + dest.writeString8(enabler); } else { dest.writeInt(0); } dest.writeParcelable(zenPolicy, 0); dest.writeParcelable(zenDeviceEffects, 0); - dest.writeString(pkg); + dest.writeString8(pkg); dest.writeBoolean(allowManualInvocation); - dest.writeString(iconResName); - dest.writeString(triggerDescription); + dest.writeString8(iconResName); + dest.writeString8(triggerDescription); dest.writeInt(type); dest.writeInt(userModifiedFields); dest.writeInt(zenPolicyUserModifiedFields); diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java index 6ed8c6d195e6..929e39f8b65c 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java @@ -421,7 +421,12 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser Intent intent = new Intent(SERVICE_INTERFACE); intent.setComponent(serviceInfo.getComponentName()); int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY; - mLifecycleExecutor.execute(() -> mContext.bindService(intent, this, flags)); + if (mServiceInfo == null) { + mLifecycleExecutor.execute(() -> mContext.bindService(intent, this, flags)); + } else { + mLifecycleExecutor.execute(() -> mContext.bindServiceAsUser(intent, this, flags, + UserHandle.of(mServiceInfo.getUserId()))); + } resetServiceConnectionTimeout(); } diff --git a/core/java/android/view/ISurfaceControlViewHost.aidl b/core/java/android/view/ISurfaceControlViewHost.aidl index fd4b329570d9..83aceb3f9a7d 100644 --- a/core/java/android/view/ISurfaceControlViewHost.aidl +++ b/core/java/android/view/ISurfaceControlViewHost.aidl @@ -21,6 +21,7 @@ import android.graphics.Rect; import android.view.InsetsState; import android.view.ISurfaceControlViewHostParent; import android.window.ISurfaceSyncGroup; +import android.window.InputTransferToken; /** * API from content embedder back to embedded content in SurfaceControlViewHost @@ -32,6 +33,7 @@ interface ISurfaceControlViewHost { * APIs that are blocking */ oneway void onConfigurationChanged(in Configuration newConfig); + oneway void onDispatchAttachedToWindow(in InputTransferToken token); oneway void onDispatchDetachedFromWindow(); oneway void onInsetsChanged(in InsetsState state, in Rect insetFrame); ISurfaceSyncGroup getSurfaceSyncGroup(); diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 4fc894ca9ff4..237d8f96496f 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -699,7 +699,7 @@ interface IWindowManager /** * Indicates the display should show system decors. * <p> - * System decors include status bar, navigation bar, launcher. + * System decors include status bar, navigation bar, launcher, and wallpaper. * </p> * * @param displayId The id of the display. @@ -719,6 +719,23 @@ interface IWindowManager void setShouldShowSystemDecors(int displayId, boolean shouldShow); /** + * Indicates that the display is eligible for the desktop mode from WindowManager's perspective. + * This includes: + * - The default display; + * - Any display that is allowed to switch the content mode between extended and mirroring + * (which means it can dynamically add or remove system decors), and it is now in extended mode + * (should currently show system decors). + * <p> + * System decors include status bar, navigation bar, launcher, and wallpaper. + * </p> + * + * @param displayId The id of the display. + * @return {@code true} if the display is eligible for the desktop mode from WindowManager's + * perspective. + */ + boolean isEligibleForDesktopMode(int displayId); + + /** * Indicates the policy for how the display should show IME. * * @param displayId The id of the display. @@ -792,7 +809,8 @@ interface IWindowManager * Updates the currently animating insets types of a remote process. */ @EnforcePermission("MANAGE_APP_TOKENS") - void updateDisplayWindowAnimatingTypes(int displayId, int animatingTypes); + void updateDisplayWindowAnimatingTypes(int displayId, int animatingTypes, + in @nullable ImeTracker.Token statsToken); /** * Called to get the expected window insets. diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 7d6d5a269b4c..a029303611c0 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -277,8 +277,10 @@ interface IWindowSession { * * @param window The window that is insets animaiton is running. * @param animatingTypes Indicates the currently animating insets types. + * @param imeStatsToken the token tracking the current IME request or {@code null} otherwise. */ - oneway void updateAnimatingTypes(IWindow window, int animatingTypes); + oneway void updateAnimatingTypes(IWindow window, int animatingTypes, + in @nullable ImeTracker.Token imeStatsToken); /** * Called when the system gesture exclusion has changed. @@ -311,8 +313,9 @@ interface IWindowSession { /** * Update the flags on an input channel associated with a particular surface. */ - oneway void updateInputChannel(in IBinder channelToken, int displayId, - in SurfaceControl surface, int flags, int privateFlags, int inputFeatures, + oneway void updateInputChannel(in IBinder channelToken, + in @nullable InputTransferToken hostInputTransferToken, + int displayId, in SurfaceControl surface, int flags, int privateFlags, int inputFeatures, in Region region); /** diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 394ac8f8c6e9..6b7b81887706 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -215,8 +215,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation * contain all types, which have an ongoing animation. * * @param animatingTypes the {@link InsetsType}s that are currently animating + * @param statsToken the token tracking the current IME request or {@code null} otherwise. */ - default void updateAnimatingTypes(@InsetsType int animatingTypes) {} + default void updateAnimatingTypes(@InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { + } /** @see ViewRootImpl#isHandlingPointerEvent */ default boolean isHandlingPointerEvent() { @@ -748,7 +751,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mFrame, mFromState, mToState, RESIZE_INTERPOLATOR, ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this); if (mRunningAnimations.isEmpty()) { - mHost.updateAnimatingTypes(runner.getTypes()); + mHost.updateAnimatingTypes(runner.getTypes(), + runner.getAnimationType() == ANIMATION_TYPE_HIDE + ? runner.getStatsToken() : null); } mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType())); mAnimatingTypes |= runner.getTypes(); @@ -1421,6 +1426,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (DEBUG) Log.d(TAG, "no types to animate in controlAnimationUnchecked"); Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0); Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0); + ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION); return; } if (DEBUG) Log.d(TAG, "controlAnimation types: " + types); @@ -1569,7 +1575,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING); mAnimatingTypes |= runner.getTypes(); - mHost.updateAnimatingTypes(mAnimatingTypes); + mHost.updateAnimatingTypes(mAnimatingTypes, null /* statsToken */); mRunningAnimations.add(new RunningAnimation(runner, animationType)); if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: " + useInsetsAnimationThread); @@ -1778,7 +1784,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation ImeTracker.forLogging().onHidden(statsToken); } } - reportRequestedVisibleTypes(shown ? null : runner.getStatsToken()); + reportRequestedVisibleTypes(null /* statsToken */); } @Override @@ -1835,7 +1841,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mHost != null) { // if the (hide) animation is cancelled, the // requestedVisibleTypes should be reported at this point. - reportRequestedVisibleTypes(control.getStatsToken()); + reportRequestedVisibleTypes(!Flags.reportAnimatingInsetsTypes() + ? control.getStatsToken() : null); mHost.getInputMethodManager().removeImeSurface( mHost.getWindowToken()); } @@ -1847,7 +1854,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } if (removedTypes > 0) { mAnimatingTypes &= ~removedTypes; - mHost.updateAnimatingTypes(mAnimatingTypes); + if (mHost != null) { + final boolean dispatchStatsToken = + Flags.reportAnimatingInsetsTypes() && (removedTypes & ime()) != 0 + && control.getAnimationType() == ANIMATION_TYPE_HIDE; + mHost.updateAnimatingTypes(mAnimatingTypes, + dispatchStatsToken ? control.getStatsToken() : null); + } } onAnimationStateChanged(removedTypes, false /* running */); @@ -2003,6 +2016,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (Flags.refactorInsetsController()) { ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES); + if (Flags.reportAnimatingInsetsTypes() && (typesToReport & ime()) == 0) { + // The IME hide animating flow should not be followed from here, but after + // the hide animation has finished and Host.updateAnimatingTypes is called. + statsToken = null; + } } mReportedRequestedVisibleTypes = mRequestedVisibleTypes; mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes, statsToken); diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 04ec4d0d382d..ecbf1f65f810 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -79,6 +79,20 @@ public class SurfaceControlViewHost { } @Override + public void onDispatchAttachedToWindow(InputTransferToken hostInputTransferToken) { + boolean hostInputTransferTokenChanged = + !Objects.equals(hostInputTransferToken, mWm.mHostInputTransferToken); + if (!hostInputTransferTokenChanged) { + return; + } + + mWm.setHostInputTransferToken(hostInputTransferToken); + if (mViewRoot != null && mViewRoot.mView != null) { + mWm.updateInputChannel(getWindowToken().asBinder()); + } + } + + @Override public void onDispatchDetachedFromWindow() { if (mViewRoot == null) { return; diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 4f6c730857a8..1b57b0045537 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -16,6 +16,7 @@ package android.view; + import static android.view.flags.Flags.FLAG_DEPRECATE_SURFACE_VIEW_Z_ORDER_APIS; import static android.view.flags.Flags.FLAG_SURFACE_VIEW_GET_SURFACE_PACKAGE; import static android.view.flags.Flags.FLAG_SURFACE_VIEW_SET_COMPOSITION_ORDER; @@ -23,6 +24,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLAY_SUBLAYER; import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER; import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER; +import static android.view.flags.Flags.FLAG_SURFACE_VIEW_GET_SURFACE_PACKAGE; +import static android.view.flags.Flags.FLAG_SURFACE_VIEW_SET_COMPOSITION_ORDER; import android.annotation.FlaggedApi; import android.annotation.FloatRange; @@ -59,6 +62,7 @@ import android.util.Log; import android.view.SurfaceControl.Transaction; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; +import android.window.InputTransferToken; import android.window.SurfaceSyncGroup; import com.android.graphics.hwui.flags.Flags; @@ -347,7 +351,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall sv.mSurfacePackage.getRemoteInterface().attachParentInterface(this); mSurfaceView = sv; } catch (RemoteException e) { - Log.d(TAG, "Failed to attach parent interface to SCVH. Likely SCVH is alraedy " + Log.d(TAG, "Failed to attach parent interface to SCVH. Likely SCVH is already " + "dead."); } } @@ -492,10 +496,37 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mTag = "SV[" + System.identityHashCode(this) + windowName + "]"; } + private void dispatchScvhAttachedToHost() { + final ViewRootImpl viewRoot = getViewRootImpl(); + if (viewRoot == null) { + return; + } + + IBinder inputToken = viewRoot.getInputToken(); + if (inputToken == null) { + // We don't have an input channel so we can't transfer focus or active + // touch gestures to embedded. + return; + } + + try { + mSurfacePackage + .getRemoteInterface() + .onDispatchAttachedToWindow(new InputTransferToken(inputToken)); + } catch (RemoteException e) { + Log.d(TAG, + "Failed to onDispatchAttachedToWindow to SCVH. Likely SCVH is already " + + "dead."); + } + } + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); setTag(); + if (mSurfacePackage != null) { + dispatchScvhAttachedToHost(); + } getViewRootImpl().addSurfaceChangedCallback(this); mWindowStopped = false; mViewVisibility = getVisibility() == VISIBLE; @@ -2189,6 +2220,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall applyTransactionOnVriDraw(transaction); } mSurfacePackage = p; + dispatchScvhAttachedToHost(); mSurfaceControlViewHostParent.attach(this); if (isFocused()) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f50d77e6aead..f32ce6f1d6e4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -34271,6 +34271,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, frameRateToSet = velocityFrameRate; } viewRootImpl.votePreferredFrameRate(frameRateToSet, compatibility); + + if (Trace.isTagEnabled(TRACE_TAG_VIEW)) { + Trace.instant(TRACE_TAG_VIEW, + getClass().getSimpleName() + + " - votePreferredFrameRate: " + frameRateToSet); + } } if (viewRootImpl.shouldCheckFrameRateCategory()) { @@ -34306,6 +34312,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, | FRAME_RATE_CATEGORY_REASON_INVALID; } } + + if (Trace.isTagEnabled(TRACE_TAG_VIEW)) { + Trace.instant(TRACE_TAG_VIEW, + getClass().getSimpleName() + " - votePreferredFrameRate: " + + viewRootImpl.categoryToString( + frameRateCategory & ~FRAME_RATE_CATEGORY_REASON_MASK)); + } } else { // Category doesn't control it. It is directly controlled by frame rate frameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 2edce5de7ace..4e3ff9063179 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -37,8 +37,8 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT; import static android.view.Surface.FRAME_RATE_CATEGORY_LOW; import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL; import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE; -import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.Surface.FRAME_RATE_COMPATIBILITY_AT_LEAST; +import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; import static android.view.View.FRAME_RATE_CATEGORY_REASON_BOOST; import static android.view.View.FRAME_RATE_CATEGORY_REASON_CONFLICTED; import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT; @@ -2555,9 +2555,11 @@ public final class ViewRootImpl implements ViewParent, /** * Notify the when the animating insets types have changed. + * + * @hide */ - @VisibleForTesting - public void updateAnimatingTypes(@InsetsType int animatingTypes) { + public void updateAnimatingTypes(@InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { if (sToolkitSetFrameRateReadOnlyFlagValue) { boolean running = animatingTypes != 0; if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { @@ -2567,7 +2569,7 @@ public final class ViewRootImpl implements ViewParent, } mInsetsAnimationRunning = running; try { - mWindowSession.updateAnimatingTypes(mWindow, animatingTypes); + mWindowSession.updateAnimatingTypes(mWindow, animatingTypes, statsToken); } catch (RemoteException e) { } } @@ -2681,7 +2683,8 @@ public final class ViewRootImpl implements ViewParent, mStopped = stopped; final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer; if (renderer != null) { - if (DEBUG_DRAW) Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped); + if (DEBUG_DRAW) + Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped); renderer.setStopped(mStopped); } if (!mStopped) { @@ -13216,7 +13219,7 @@ public final class ViewRootImpl implements ViewParent, } } - private static String categoryToString(int frameRateCategory) { + static String categoryToString(int frameRateCategory) { String category; switch (frameRateCategory) { case FRAME_RATE_CATEGORY_NO_PREFERENCE -> category = "no preference"; diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java index 8954df6b1aaa..20fa77bf56ea 100644 --- a/core/java/android/view/ViewRootInsetsControllerHost.java +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -171,9 +171,15 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { } @Override - public void updateAnimatingTypes(@WindowInsets.Type.InsetsType int animatingTypes) { + public void updateAnimatingTypes(@WindowInsets.Type.InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { if (mViewRoot != null) { - mViewRoot.updateAnimatingTypes(animatingTypes); + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_UPDATE_ANIMATING_TYPES); + mViewRoot.updateAnimatingTypes(animatingTypes, statsToken); + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_CLIENT_UPDATE_ANIMATING_TYPES); } } diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index 3b444c44c368..fc66e49ff6b0 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -16,6 +16,9 @@ package android.view; +import static android.view.flags.Flags.FLAG_ENABLE_DISPATCH_ON_SCROLL_CHANGED; + +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -1258,8 +1261,9 @@ public final class ViewTreeObserver { /** * Notifies registered listeners that something has scrolled. */ + @FlaggedApi(FLAG_ENABLE_DISPATCH_ON_SCROLL_CHANGED) @UnsupportedAppUsage - final void dispatchOnScrollChanged() { + public final void dispatchOnScrollChanged() { // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to // perform the dispatching. The iterator is a safe guard against listeners that // could mutate the list by calling the various add/remove methods. This prevents diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 39533344173b..9097849085a9 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1840,6 +1840,16 @@ public abstract class Window { @NonNull public abstract LayoutInflater getLayoutInflater(); + /** + * Sets a user-facing title for the window. + * <p> + * This title may be shown to the user in the window's title or action bar + * if the {@link #requestFeature requested features} provide such a bar. + * It is also exposed through {@link + * android.view.accessibility.AccessibilityWindowInfo#getTitle}. + * + * @see WindowManager.LayoutParams#setTitle + */ public abstract void setTitle(CharSequence title); @Deprecated diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 315f1ba58529..9d21f1aff0c3 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -5095,6 +5095,15 @@ public interface WindowManager extends ViewManager { format = _format; } + /** + * Sets a title for the window. + * <p> + * This title will be used primarily for debugging, and may be exposed via {@link + * android.view.accessibility.AccessibilityWindowInfo#getTitle} if no {@link Window#setTitle + * user-facing title} has been set. + * + * @see Window#setTitle + */ public final void setTitle(CharSequence title) { if (null == title) title = ""; diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 0a86ff89c53c..5af4abd1f608 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -89,7 +89,7 @@ public class WindowlessWindowManager implements IWindowSession { protected final SurfaceControl mRootSurface; private final Configuration mConfiguration; private final IWindowSession mRealWm; - final InputTransferToken mHostInputTransferToken; + InputTransferToken mHostInputTransferToken; private final InputTransferToken mInputTransferToken = new InputTransferToken(); private InsetsState mInsetsState; private final ClientWindowFrames mTmpFrames = new ClientWindowFrames(); @@ -128,9 +128,11 @@ public class WindowlessWindowManager implements IWindowSession { return null; } - /** - * Utility API. - */ + void setHostInputTransferToken(InputTransferToken token) { + mHostInputTransferToken = token; + } + + /** Utility API. */ void setCompletionCallback(IBinder window, ResizeCompleteCallback callback) { if (mResizeCompletionForWindow.get(window) != null) { Log.w(TAG, "Unsupported overlapping resizes"); @@ -151,11 +153,25 @@ public class WindowlessWindowManager implements IWindowSession { return; } state.mInputRegion = region != null ? new Region(region) : null; + updateInputChannel(window); + } + } + + protected void updateInputChannel(IBinder window) { + State state; + synchronized (this) { + // Do everything while locked so that we synchronize with relayout. This should be a + // very infrequent operation. + state = mStateForWindow.get(window); + if (state == null) { + return; + } if (state.mInputChannelToken != null) { try { - mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, - state.mSurfaceControl, state.mParams.flags, state.mParams.privateFlags, - state.mParams.inputFeatures, state.mInputRegion); + mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken, + state.mDisplayId, state.mSurfaceControl, state.mParams.flags, + state.mParams.privateFlags, state.mParams.inputFeatures, + state.mInputRegion); } catch (RemoteException e) { Log.e(TAG, "Failed to update surface input channel: ", e); } @@ -174,9 +190,7 @@ public class WindowlessWindowManager implements IWindowSession { } } - /** - * IWindowSession implementation. - */ + /** IWindowSession implementation. */ @Override public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, @InsetsType int requestedVisibleTypes, @@ -437,14 +451,15 @@ public class WindowlessWindowManager implements IWindowSession { if ((attrChanges & inputChangeMask) != 0 && state.mInputChannelToken != null) { try { if (mRealWm instanceof IWindowSession.Stub) { - mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, + mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken, + state.mDisplayId, new SurfaceControl(sc, "WindowlessWindowManager.relayout"), attrs.flags, attrs.privateFlags, attrs.inputFeatures, state.mInputRegion); } else { - mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc, - attrs.flags, attrs.privateFlags, attrs.inputFeatures, - state.mInputRegion); + mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken, + state.mDisplayId, sc, attrs.flags, attrs.privateFlags, + attrs.inputFeatures, state.mInputRegion); } } catch (RemoteException e) { Log.e(TAG, "Failed to update surface input channel: ", e); @@ -597,7 +612,8 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes) { + public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { // NO-OP } @@ -623,8 +639,9 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, - int flags, int privateFlags, int inputFeatures, Region region) { + public void updateInputChannel(IBinder channelToken, InputTransferToken hostInputToken, + int displayId, SurfaceControl surface, int flags, int privateFlags, int inputFeatures, + Region region) { } @Override diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java index 7b6e070f0008..c17002ed706e 100644 --- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java +++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java @@ -160,6 +160,9 @@ public final class AccessibilityWindowInfo implements Parcelable { /** * Gets the title of the window. + * <p> + * This is taken from the {@link android.view.Window}'s title, or its {@link + * android.view.WindowManager.LayoutParams} if that is unset. * * @return The title of the window, or {@code null} if none is available. */ diff --git a/core/java/android/view/flags/view_tree_observer_flags.aconfig b/core/java/android/view/flags/view_tree_observer_flags.aconfig new file mode 100644 index 000000000000..82f3300a87cb --- /dev/null +++ b/core/java/android/view/flags/view_tree_observer_flags.aconfig @@ -0,0 +1,9 @@ +package: "android.view.flags" +container: "system" + +flag { + name: "enable_dispatch_on_scroll_changed" + namespace: "toolkit" + description: "Feature flag for enabling the dispatchOnScrollChanged method in ViewTreeObserver." + bug: "238109286" +}
\ No newline at end of file diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java index 60178cde249f..5dadf32d2a36 100644 --- a/core/java/android/view/inputmethod/ImeTracker.java +++ b/core/java/android/view/inputmethod/ImeTracker.java @@ -226,6 +226,11 @@ public interface ImeTracker { PHASE_WM_DISPLAY_IME_CONTROLLER_SET_IME_REQUESTED_VISIBLE, PHASE_WM_UPDATE_DISPLAY_WINDOW_REQUESTED_VISIBLE_TYPES, PHASE_WM_REQUESTED_VISIBLE_TYPES_NOT_CHANGED, + PHASE_CLIENT_UPDATE_ANIMATING_TYPES, + PHASE_WM_UPDATE_ANIMATING_TYPES, + PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED, + PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED, + PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES, }) @Retention(RetentionPolicy.SOURCE) @interface Phase {} @@ -449,6 +454,21 @@ public interface ImeTracker { /** The requestedVisibleTypes have not been changed, so this request is not continued. */ int PHASE_WM_REQUESTED_VISIBLE_TYPES_NOT_CHANGED = ImeProtoEnums.PHASE_WM_REQUESTED_VISIBLE_TYPES_NOT_CHANGED; + /** Updating the currently animating types on the client side. */ + int PHASE_CLIENT_UPDATE_ANIMATING_TYPES = + ImeProtoEnums.PHASE_CLIENT_UPDATE_ANIMATING_TYPES; + /** Updating the animating types in the WindowState on the WindowManager side. */ + int PHASE_WM_UPDATE_ANIMATING_TYPES = + ImeProtoEnums.PHASE_WM_UPDATE_ANIMATING_TYPES; + /** Animating types of the WindowState have changed, now sending them to state controller. */ + int PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED = + ImeProtoEnums.PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED; + /** ImeInsetsSourceProvider got notified that the hide animation is finished. */ + int PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED = + ImeProtoEnums.PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED; + /** The control target reported its animatingTypes back to WindowManagerService. */ + int PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES = + ImeProtoEnums.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES; /** * Called when an IME request is started. diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index a41ab368aed8..b3bd89c2a87d 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -2454,6 +2454,7 @@ public final class InputMethodManager { & WindowInsets.Type.ime()) == 0 || viewRootImpl.getInsetsController() .isPredictiveBackImeHideAnimInProgress())) { + Handler vh = view.getHandler(); ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_NO_ONGOING_USER_ANIMATION); if (resultReceiver != null) { @@ -2464,8 +2465,17 @@ public final class InputMethodManager { : InputMethodManager.RESULT_SHOWN, null); } // TODO(b/322992891) handle case of SHOW_IMPLICIT - viewRootImpl.getInsetsController().show(WindowInsets.Type.ime(), - false /* fromIme */, statsToken); + if (vh.getLooper() != Looper.myLooper()) { + // The view is running on a different thread than our own, so + // we need to reschedule our work for over there. + if (DEBUG) Log.v(TAG, "Show soft input: reschedule to view thread"); + final var finalStatsToken = statsToken; + vh.post(() -> viewRootImpl.getInsetsController().show( + WindowInsets.Type.ime(), false /* fromIme */, finalStatsToken)); + } else { + viewRootImpl.getInsetsController().show(WindowInsets.Type.ime(), + false /* fromIme */, statsToken); + } return true; } ImeTracker.forLogging().onCancelled(statsToken, diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig index 67e54423414c..cdca4102dd96 100644 --- a/core/java/android/view/inputmethod/flags.aconfig +++ b/core/java/android/view/inputmethod/flags.aconfig @@ -224,3 +224,14 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "disallow_disabling_ime_navigation_bar" + namespace: "input_method" + description: "Disallows disabling the IME navigation bar through canImeRenderGesturalNavButtons" + bug: "402442590" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 222a7b38c966..3dfbc2517986 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -9216,7 +9216,13 @@ public class RemoteViews implements Parcelable, Filter { public static RemoteResponse fromFillInIntent(@NonNull Intent fillIntent) { RemoteResponse response = new RemoteResponse(); response.mFillIntent = fillIntent; - fillIntent.collectExtraIntentKeys(); + if (fillIntent != null) { + // Although the parameter is marked as @NonNull, it is nullable. The method that + // calls it (RemoteReviews.setOnClickFillInIntent()) passes its fillInIntent + // parameter to this method and it does not guarantee that the fillInIntent is + // non-null. + fillIntent.collectExtraIntentKeys(); + } return response; } diff --git a/core/java/android/window/DesktopExperienceFlags.java b/core/java/android/window/DesktopExperienceFlags.java index 50b8bd22350c..5e8ce5ee557f 100644 --- a/core/java/android/window/DesktopExperienceFlags.java +++ b/core/java/android/window/DesktopExperienceFlags.java @@ -61,6 +61,7 @@ public enum DesktopExperienceFlags { ENABLE_DISPLAY_RECONNECT_INTERACTION(Flags::enableDisplayReconnectInteraction, false), ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING(Flags::enableDisplayWindowingModeSwitching, true), ENABLE_DRAG_TO_MAXIMIZE(Flags::enableDragToMaximize, true), + ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX(Flags::enableDynamicRadiusComputationBugfix, false), ENABLE_KEYBOARD_SHORTCUTS_TO_SWITCH_DESKS(Flags::keyboardShortcutsToSwitchDesks, false), ENABLE_MOVE_TO_NEXT_DISPLAY_SHORTCUT(Flags::enableMoveToNextDisplayShortcut, true), ENABLE_MULTIPLE_DESKTOPS_BACKEND(Flags::enableMultipleDesktopsBackend, false), diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java index aecf6eb261b1..5b3044e1988a 100644 --- a/core/java/android/window/DesktopModeFlags.java +++ b/core/java/android/window/DesktopModeFlags.java @@ -146,6 +146,8 @@ public enum DesktopModeFlags { Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true), INHERIT_TASK_BOUNDS_FOR_TRAMPOLINE_TASK_LAUNCHES( Flags::inheritTaskBoundsForTrampolineTaskLaunches, false), + SKIP_DECOR_VIEW_RELAYOUT_WHEN_CLOSING_BUGFIX( + Flags::skipDecorViewRelayoutWhenClosingBugfix, false), // go/keep-sorted end ; diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig index 53db2b1178cf..e4142a171669 100644 --- a/core/java/android/window/flags/lse_desktop_experience.aconfig +++ b/core/java/android/window/flags/lse_desktop_experience.aconfig @@ -595,6 +595,13 @@ flag { } flag { + name: "nested_tasks_with_independent_bounds" + namespace: "lse_desktop_experience" + description: "Allows tasks under a root task to be have independent (non-inherited) bounds" + bug: "402825303" +} + +flag { name: "enable_multiple_desktops_backend" namespace: "lse_desktop_experience" description: "Enable multiple desktop sessions for desktop windowing (backend)." @@ -933,6 +940,16 @@ flag { } flag { + name: "skip_decor_view_relayout_when_closing_bugfix" + namespace: "lse_desktop_experience" + description: "Enables bugfix to skip DecorView relayout when the corresponding window is closing." + bug: "394502142" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "enable_size_compat_mode_improvements_for_connected_displays" namespace: "lse_desktop_experience" description: "Enable some improvements in size compat mode for connected displays." @@ -962,3 +979,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "show_home_behind_desktop" + namespace: "lse_desktop_experience" + description: "Enables the home to be shown behind the desktop." + bug: "375644149" +} diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig index d866b0e2f89e..756288bdf5bf 100644 --- a/core/java/android/window/flags/window_surfaces.aconfig +++ b/core/java/android/window/flags/window_surfaces.aconfig @@ -118,3 +118,15 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "update_host_input_transfer_token" + namespace: "window_surfaces" + description: "Update host InpuTransferToken on view attach" + is_fixed_read_only: true + is_exported: true + bug: "392965431" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig index 816270235446..8dd0457248a4 100644 --- a/core/java/android/window/flags/windowing_frontend.aconfig +++ b/core/java/android/window/flags/windowing_frontend.aconfig @@ -287,6 +287,17 @@ flag { } flag { + name: "use_visible_requested_for_process_tracker" + namespace: "windowing_frontend" + description: "Do not count closing activity as visible process" + bug: "396653764" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "ensure_wallpaper_in_transitions" namespace: "windowing_frontend" description: "Ensure that wallpaper window tokens are always present/available for collection in transitions" diff --git a/core/java/com/android/internal/app/ChooserGridLayoutManager.java b/core/java/com/android/internal/app/ChooserGridLayoutManager.java index 69d2abc7d998..6eb5e74232c2 100644 --- a/core/java/com/android/internal/app/ChooserGridLayoutManager.java +++ b/core/java/com/android/internal/app/ChooserGridLayoutManager.java @@ -25,7 +25,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo; -import android.widget.GridView; +import android.widget.ListView; import android.widget.TextView; import com.android.internal.R; @@ -131,7 +131,7 @@ public class ChooserGridLayoutManager extends GridLayoutManager { super.onInitializeAccessibilityNodeInfoForItem(recycler, state, host, info); if (announceShortcutsAndSuggestedAppsLegacy() && host instanceof ViewGroup) { if (host.getId() == R.id.shortcuts_container) { - info.setClassName(GridView.class.getName()); + info.setClassName(ListView.class.getName()); info.setContainerTitle(mShortcutGroupTitle); info.setCollectionInfo(createShortcutsA11yCollectionInfo((ViewGroup) host)); } else if (host.getId() == R.id.chooser_row) { @@ -140,7 +140,7 @@ public class ChooserGridLayoutManager extends GridLayoutManager { ChooserListAdapter gridAdapter = adapter instanceof ChooserGridAdapter ? ((ChooserGridAdapter) adapter).getListAdapter() : null; - info.setClassName(GridView.class.getName()); + info.setClassName(ListView.class.getName()); info.setCollectionInfo(createSuggestedAppsA11yCollectionInfo((ViewGroup) host)); if (gridAdapter == null || gridAdapter.getAlphaTargetCount() > 0) { info.setContainerTitle(mSuggestedAppsGroupTitle); diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java index 41e2ca9cdfad..e125e258c596 100644 --- a/core/java/com/android/internal/jank/Cuj.java +++ b/core/java/com/android/internal/jank/Cuj.java @@ -313,8 +313,17 @@ public class Cuj { */ public static final int CUJ_DEFAULT_TASK_TO_TASK_ANIMATION = 128; + /** + * Track moving a window to another display in Desktop Windowing mode. + * + * <p>Tracking starts when the DesktopModeMoveToDisplayTransitionHandler starts animating the + * task to move it to another display. This is triggered when the user presses a keyboard + * shortcut or clicks the menu in the overview. Tracking ends when the animation completes.</p> + */ + public static final int CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY = 129; + // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE. - @VisibleForTesting static final int LAST_CUJ = CUJ_DEFAULT_TASK_TO_TASK_ANIMATION; + @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY; /** @hide */ @IntDef({ @@ -434,7 +443,8 @@ public class Cuj { CUJ_DESKTOP_MODE_KEYBOARD_QUICK_SWITCH_APP_LAUNCH, CUJ_LAUNCHER_WORK_UTILITY_VIEW_EXPAND, CUJ_LAUNCHER_WORK_UTILITY_VIEW_SHRINK, - CUJ_DEFAULT_TASK_TO_TASK_ANIMATION + CUJ_DEFAULT_TASK_TO_TASK_ANIMATION, + CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY }) @Retention(RetentionPolicy.SOURCE) public @interface CujType {} @@ -565,6 +575,7 @@ public class Cuj { CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WORK_UTILITY_VIEW_EXPAND] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WORK_UTILITY_VIEW_EXPAND; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WORK_UTILITY_VIEW_SHRINK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WORK_UTILITY_VIEW_SHRINK; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DEFAULT_TASK_TO_TASK_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DEFAULT_TASK_TO_TASK_ANIMATION; + CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY; } private Cuj() { @@ -817,6 +828,8 @@ public class Cuj { return "LAUNCHER_WORK_UTILITY_VIEW_SHRINK"; case CUJ_DEFAULT_TASK_TO_TASK_ANIMATION: return "DEFAULT_TASK_TO_TASK_ANIMATION"; + case CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY: + return "DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java index c6207f9451c2..8151429f9139 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -672,6 +672,7 @@ public class BatteryStatsHistory { */ public void reset() { synchronized (this) { + mMonotonicHistorySize = 0; initHistoryBuffer(); if (mStore != null) { mStore.reset(); diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 3f9650773211..d35072fc10c3 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -22,7 +22,6 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; -import static android.security.Flags.reportPrimaryAuthAttempts; import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth; import static com.android.internal.widget.flags.Flags.hideLastCharWithPhysicalInput; @@ -472,7 +471,7 @@ public class LockPatternUtils { return; } getDevicePolicyManager().reportFailedPasswordAttempt(userId); - if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) { + if (!shouldTrustManagerListenForPrimaryAuth()) { getTrustManager().reportUnlockAttempt(/* authenticated= */ false, userId); } } @@ -483,7 +482,7 @@ public class LockPatternUtils { return; } getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId); - if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) { + if (!shouldTrustManagerListenForPrimaryAuth()) { getTrustManager().reportUnlockAttempt(/* authenticated= */ true, userId); } } diff --git a/core/java/com/android/internal/widget/NotificationCloseButton.java b/core/java/com/android/internal/widget/NotificationCloseButton.java index bce266d71e43..0d801b1fb643 100644 --- a/core/java/com/android/internal/widget/NotificationCloseButton.java +++ b/core/java/com/android/internal/widget/NotificationCloseButton.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; import android.util.AttributeSet; import android.view.RemotableViewMethod; import android.view.View; @@ -40,6 +42,8 @@ public class NotificationCloseButton extends ImageView { @ColorInt private int mBackgroundColor; @ColorInt private int mForegroundColor; + private Drawable mPillDrawable; + public NotificationCloseButton(Context context) { this(context, null, 0, 0); } @@ -62,6 +66,10 @@ public class NotificationCloseButton extends ImageView { protected void onFinishInflate() { super.onFinishInflate(); setContentDescription(mContext.getText(R.string.close_button_text)); + + final LayerDrawable layeredPill = (LayerDrawable) this.getBackground(); + mPillDrawable = layeredPill.findDrawableByLayerId(R.id.close_button_pill_colorized_layer); + boolean notificationCloseButtonSupported = Resources.getSystem().getBoolean( com.android.internal.R.bool.config_notificationCloseButtonSupported); this.setVisibility(notificationCloseButtonSupported ? View.VISIBLE : View.GONE); @@ -76,8 +84,11 @@ public class NotificationCloseButton extends ImageView { private void updateColors() { if (mBackgroundColor != 0) { - this.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor)); + // TODO(http://b/365585705): Ensure this close button compatible with the ongoing effort + // that makes notification rows partially-transparent. + this.mPillDrawable.setTintList(ColorStateList.valueOf(mBackgroundColor)); } + if (mForegroundColor != 0) { this.setImageTintList(ColorStateList.valueOf(mForegroundColor)); } diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java b/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java index a53d6b899898..3fe6873028cd 100644 --- a/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java +++ b/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java @@ -132,8 +132,13 @@ public class AndroidPlatformSemanticNodeApplier } } - // TODO correct values - nodeInfo.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(-1, 1, false)); + if (scrollDirection == RootContentBehavior.SCROLL_HORIZONTAL) { + nodeInfo.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(1, -1, false)); + nodeInfo.setClassName("android.widget.HorizontalScrollView"); + } else { + nodeInfo.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(-1, 1, false)); + nodeInfo.setClassName("android.widget.ScrollView"); + } if (scrollDirection == RootContentBehavior.SCROLL_HORIZONTAL) { nodeInfo.setClassName("android.widget.HorizontalScrollView"); diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java b/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java index f70f4cbceb70..db2c46046561 100644 --- a/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java +++ b/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java @@ -33,6 +33,7 @@ import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySem import com.android.internal.widget.remotecompose.core.semantics.AccessibleComponent; import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics; import com.android.internal.widget.remotecompose.core.semantics.ScrollableComponent; +import com.android.internal.widget.remotecompose.core.semantics.ScrollableComponent.ScrollDirection; import java.util.ArrayList; import java.util.Collections; @@ -104,9 +105,9 @@ public class CoreDocumentAccessibility implements RemoteComposeDocumentAccessibi if (isClickAction(action)) { return performClick(component); } else if (isScrollForwardAction(action)) { - return scrollByOffset(mRemoteContext, component, -500) != 0; + return scrollDirection(mRemoteContext, component, ScrollDirection.FORWARD); } else if (isScrollBackwardAction(action)) { - return scrollByOffset(mRemoteContext, component, 500) != 0; + return scrollDirection(mRemoteContext, component, ScrollDirection.BACKWARD); } else if (isShowOnScreenAction(action)) { return showOnScreen(mRemoteContext, component); } else { @@ -141,17 +142,30 @@ public class CoreDocumentAccessibility implements RemoteComposeDocumentAccessibi } private boolean showOnScreen(RemoteContext context, Component component) { - if (component.getParent() instanceof LayoutComponent) { - LayoutComponent parent = (LayoutComponent) component.getParent(); + ScrollableComponent scrollable = findScrollable(component); + + if (scrollable != null) { + return scrollable.showOnScreen(context, component); + } + + return false; + } + + @Nullable + private static ScrollableComponent findScrollable(Component component) { + Component parent = component.getParent(); + + while (parent != null) { ScrollableComponent scrollable = parent.selfOrModifier(ScrollableComponent.class); if (scrollable != null) { - scrollable.showOnScreen(context, component.getComponentId()); - return true; + return scrollable; + } else { + parent = parent.getParent(); } } - return false; + return null; } /** @@ -173,6 +187,25 @@ public class CoreDocumentAccessibility implements RemoteComposeDocumentAccessibi } /** + * scroll content in a given direction + * + * @param context + * @param component + * @param direction + * @return + */ + public boolean scrollDirection( + RemoteContext context, Component component, ScrollDirection direction) { + ScrollableComponent scrollable = component.selfOrModifier(ScrollableComponent.class); + + if (scrollable != null) { + return scrollable.scrollDirection(context, direction); + } + + return false; + } + + /** * Perform a click on the given component * * @param component diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java index c38a44ac30be..da4e8d621602 100644 --- a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java +++ b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java @@ -39,6 +39,7 @@ public class PlatformRemoteComposeTouchHelper extends ExploreByTouchHelper { private final RemoteComposeDocumentAccessibility mRemoteDocA11y; private final SemanticNodeApplier<AccessibilityNodeInfo> mApplier; + private final View mHost; public PlatformRemoteComposeTouchHelper( View host, @@ -47,6 +48,7 @@ public class PlatformRemoteComposeTouchHelper extends ExploreByTouchHelper { super(host); this.mRemoteDocA11y = remoteDocA11y; this.mApplier = applier; + this.mHost = host; } public static PlatformRemoteComposeTouchHelper forRemoteComposePlayer( @@ -150,6 +152,7 @@ public class PlatformRemoteComposeTouchHelper extends ExploreByTouchHelper { boolean performed = mRemoteDocA11y.performAction(component, action, arguments); if (performed) { + mHost.invalidate(); invalidateRoot(); } diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java index caf19e1ed34a..766fbf1a80f5 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java +++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java @@ -73,7 +73,9 @@ public class CoreDocument implements Serializable { // We also keep a more fine-grained BUILD number, exposed as // ID_API_LEVEL = DOCUMENT_API_LEVEL + BUILD - static final float BUILD = 0.5f; + static final float BUILD = 0.7f; + + private static final boolean UPDATE_VARIABLES_BEFORE_LAYOUT = false; @NonNull ArrayList<Operation> mOperations = new ArrayList<>(); @@ -840,18 +842,25 @@ public class CoreDocument implements Serializable { @NonNull private HashMap<Integer, Component> mComponentMap = new HashMap<Integer, Component>(); + /** + * Register all the operations recursively + * + * @param context + * @param list + */ private void registerVariables( @NonNull RemoteContext context, @NonNull ArrayList<Operation> list) { for (Operation op : list) { if (op instanceof VariableSupport) { - ((VariableSupport) op).updateVariables(context); ((VariableSupport) op).registerListening(context); } if (op instanceof Component) { mComponentMap.put(((Component) op).getComponentId(), (Component) op); - registerVariables(context, ((Component) op).getList()); ((Component) op).registerVariables(context); } + if (op instanceof Container) { + registerVariables(context, ((Container) op).getList()); + } if (op instanceof ComponentValue) { ComponentValue v = (ComponentValue) op; Component component = mComponentMap.get(v.getComponentId()); @@ -864,14 +873,34 @@ public class CoreDocument implements Serializable { if (op instanceof ComponentModifiers) { for (ModifierOperation modifier : ((ComponentModifiers) op).getList()) { if (modifier instanceof VariableSupport) { - ((VariableSupport) modifier).updateVariables(context); ((VariableSupport) modifier).registerListening(context); } } } + } + } + + /** + * Apply the operations recursively, for the original initialization pass with mode == DATA + * + * @param context + * @param list + */ + private void applyOperations( + @NonNull RemoteContext context, @NonNull ArrayList<Operation> list) { + for (Operation op : list) { + if (op instanceof VariableSupport) { + ((VariableSupport) op).updateVariables(context); + } + if (op instanceof Component) { // for componentvalues... + ((Component) op).updateVariables(context); + } op.markNotDirty(); op.apply(context); context.incrementOpCount(); + if (op instanceof Container) { + applyOperations(context, ((Container) op).getList()); + } } } @@ -891,8 +920,12 @@ public class CoreDocument implements Serializable { mTimeVariables.updateTime(context); registerVariables(context, mOperations); + applyOperations(context, mOperations); context.mMode = RemoteContext.ContextMode.UNSET; - mFirstPaint = true; + + if (UPDATE_VARIABLES_BEFORE_LAYOUT) { + mFirstPaint = true; + } } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -1241,11 +1274,13 @@ public class CoreDocument implements Serializable { context.mRemoteComposeState = mRemoteComposeState; context.mRemoteComposeState.setContext(context); - // Update any dirty variables - if (mFirstPaint) { - mFirstPaint = false; - } else { - updateVariables(context, theme, mOperations); + if (UPDATE_VARIABLES_BEFORE_LAYOUT) { + // Update any dirty variables + if (mFirstPaint) { + mFirstPaint = false; + } else { + updateVariables(context, theme, mOperations); + } } // If we have a content sizing set, we are going to take the original document diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java index ac9f98bd6b15..add9d5bae552 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java +++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java @@ -111,6 +111,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.managers import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentVisibilityOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.DrawContentOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.GraphicsLayerModifierOperation; @@ -257,6 +258,7 @@ public class Operations { public static final int MODIFIER_HEIGHT = 67; public static final int MODIFIER_WIDTH_IN = 231; public static final int MODIFIER_HEIGHT_IN = 232; + public static final int MODIFIER_COLLAPSIBLE_PRIORITY = 235; public static final int MODIFIER_BACKGROUND = 55; public static final int MODIFIER_BORDER = 107; public static final int MODIFIER_PADDING = 58; @@ -368,6 +370,7 @@ public class Operations { map.put(MODIFIER_HEIGHT, HeightModifierOperation::read); map.put(MODIFIER_WIDTH_IN, WidthInModifierOperation::read); map.put(MODIFIER_HEIGHT_IN, HeightInModifierOperation::read); + map.put(MODIFIER_COLLAPSIBLE_PRIORITY, CollapsiblePriorityModifierOperation::read); map.put(MODIFIER_PADDING, PaddingModifierOperation::read); map.put(MODIFIER_BACKGROUND, BackgroundModifierOperation::read); map.put(MODIFIER_BORDER, BorderModifierOperation::read); diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java index e37833f33fa5..b297a023d03b 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java +++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java @@ -46,7 +46,7 @@ public abstract class RemoteContext { new CoreDocument(); // todo: is this a valid way to initialize? bbade@ public @NonNull RemoteComposeState mRemoteComposeState = new RemoteComposeState(); // todo, is this a valid use of RemoteComposeState -- bbade@ - + private long mDocLoadTime = System.currentTimeMillis(); @Nullable protected PaintContext mPaintContext = null; protected float mDensity = Float.NaN; @@ -83,6 +83,20 @@ public abstract class RemoteContext { } } + /** + * Get the time the document was loaded + * + * @return time in ms since the document was loaded + */ + public long getDocLoadTime() { + return mDocLoadTime; + } + + /** Set the time the document was loaded */ + public void setDocLoadTime() { + mDocLoadTime = System.currentTimeMillis(); + } + public boolean isAnimationEnabled() { return mAnimate; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java index eba201bfb216..0901ae3eca75 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java @@ -149,7 +149,6 @@ public class FloatExpression extends Operation implements VariableSupport, Seria @Override public void apply(@NonNull RemoteContext context) { - updateVariables(context); float t = context.getAnimationTime(); if (Float.isNaN(mLastChange)) { mLastChange = t; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java index ee9e7a4045cb..e86eabffbeaf 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java @@ -23,6 +23,8 @@ import android.annotation.NonNull; import com.android.internal.widget.remotecompose.core.Operation; import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.PaintContext; +import com.android.internal.widget.remotecompose.core.PaintOperation; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.VariableSupport; import com.android.internal.widget.remotecompose.core.WireBuffer; @@ -30,6 +32,7 @@ import com.android.internal.widget.remotecompose.core.documentation.Documentatio import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression; import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap; +import com.android.internal.widget.remotecompose.core.serialize.MapSerializer; import java.util.Arrays; import java.util.List; @@ -38,7 +41,7 @@ import java.util.List; * This creates a particle system. which consist of id, particleCount, array of id's and equations * for constructing the particles */ -public class ParticlesCreate extends Operation implements VariableSupport { +public class ParticlesCreate extends PaintOperation implements VariableSupport { private static final int OP_CODE = Operations.PARTICLE_DEFINE; private static final String CLASS_NAME = "ParticlesCreate"; private final int mId; @@ -214,6 +217,13 @@ public class ParticlesCreate extends Operation implements VariableSupport { return indent + toString(); } + @Override + public void paint(@NonNull PaintContext context) { + for (int i = 0; i < mParticles.length; i++) { + initializeParticle(i); + } + } + void initializeParticle(int pNo) { for (int j = 0; j < mParticles[pNo].length; j++) { for (int k = 0; k < mIndexeVars.length; k++) { @@ -226,13 +236,6 @@ public class ParticlesCreate extends Operation implements VariableSupport { } } - @Override - public void apply(@NonNull RemoteContext context) { - for (int i = 0; i < mParticles.length; i++) { - initializeParticle(i); - } - } - public float[][] getParticles() { return mParticles; } @@ -244,4 +247,7 @@ public class ParticlesCreate extends Operation implements VariableSupport { public float[][] getEquations() { return mOutEquations; } + + @Override + public void serialize(MapSerializer serializer) {} } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java index 8a747e134897..31d21c4d539c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java @@ -258,6 +258,6 @@ public class PathAppend extends PaintOperation implements VariableSupport, Seria @Override public void serialize(MapSerializer serializer) { - serializer.addType(CLASS_NAME).add("id", mInstanceId).add("path", pathString(mFloatPath)); + serializer.addType(CLASS_NAME).add("id", mInstanceId).addPath("path", mFloatPath); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java index 78e3b9eac110..7a28992496b4 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java @@ -242,6 +242,6 @@ public class PathCreate extends PaintOperation implements VariableSupport, Seria @Override public void serialize(MapSerializer serializer) { - serializer.addType(CLASS_NAME).add("id", mInstanceId).add("path", pathString(mFloatPath)); + serializer.addType(CLASS_NAME).add("id", mInstanceId).addPath("path", mFloatPath); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java index cedc4f3b0e45..8b01722aea86 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java @@ -243,6 +243,6 @@ public class PathData extends Operation implements VariableSupport, Serializable @Override public void serialize(MapSerializer serializer) { - serializer.addType(CLASS_NAME).add("id", mInstanceId).add("path", pathString(mFloatPath)); + serializer.addType(CLASS_NAME).add("id", mInstanceId).addPath("path", mFloatPath); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java index e9cc26f58c9b..dee79a45de3d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java @@ -85,6 +85,9 @@ public class TimeAttribute extends PaintOperation { /** the year */ public static final short TIME_YEAR = 12; + /** (value - doc_load_time) * 1E-3 */ + public static final short TIME_FROM_LOAD_SEC = 14; + /** * creates a new operation * @@ -226,6 +229,7 @@ public class TimeAttribute extends PaintOperation { int val = mType & 255; int flags = mType >> 8; RemoteContext ctx = context.getContext(); + long load_time = ctx.getDocLoadTime(); LongConstant longConstant = (LongConstant) ctx.getObject(mTimeId); long value = longConstant.getValue(); long delta = 0; @@ -292,6 +296,9 @@ public class TimeAttribute extends PaintOperation { case TIME_YEAR: ctx.loadFloat(mId, time.getYear()); break; + case TIME_FROM_LOAD_SEC: + ctx.loadFloat(mId, (value - load_time) * 1E-3f); + break; } } @@ -334,6 +341,8 @@ public class TimeAttribute extends PaintOperation { return "TIME_DAY_OF_WEEK"; case TIME_YEAR: return "TIME_YEAR"; + case TIME_FROM_LOAD_SEC: + return "TIME_FROM_LOAD_SEC"; default: return "INVALID_TIME_TYPE"; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java index f1158d91f94b..425c61b636c4 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java @@ -175,20 +175,25 @@ public class Component extends PaintOperation + mComponentId); } for (ComponentValue v : mComponentValues) { - switch (v.getType()) { - case ComponentValue.WIDTH: - context.loadFloat(v.getValueId(), mWidth); - if (DEBUG) { - System.out.println("Updating WIDTH for " + mComponentId + " to " + mWidth); - } - break; - case ComponentValue.HEIGHT: - context.loadFloat(v.getValueId(), mHeight); - if (DEBUG) { - System.out.println( - "Updating HEIGHT for " + mComponentId + " to " + mHeight); - } - break; + if (context.getMode() == RemoteContext.ContextMode.DATA) { + context.loadFloat(v.getValueId(), 1f); + } else { + switch (v.getType()) { + case ComponentValue.WIDTH: + context.loadFloat(v.getValueId(), mWidth); + if (DEBUG) { + System.out.println( + "Updating WIDTH for " + mComponentId + " to " + mWidth); + } + break; + case ComponentValue.HEIGHT: + context.loadFloat(v.getValueId(), mHeight); + if (DEBUG) { + System.out.println( + "Updating HEIGHT for " + mComponentId + " to " + mHeight); + } + break; + } } } } @@ -824,15 +829,27 @@ public class Component extends PaintOperation * * @param value a 2 dimension float array that will receive the horizontal and vertical position * of the component. + * @param forSelf whether the location is for this container or a child, relevant for scrollable + * items. */ - public void getLocationInWindow(@NonNull float[] value) { + public void getLocationInWindow(@NonNull float[] value, boolean forSelf) { value[0] += mX; value[1] += mY; if (mParent != null) { - mParent.getLocationInWindow(value); + mParent.getLocationInWindow(value, false); } } + /** + * Returns the location of the component relative to the root component + * + * @param value a 2 dimension float array that will receive the horizontal and vertical position + * of the component. + */ + public void getLocationInWindow(@NonNull float[] value) { + getLocationInWindow(value, true); + } + @NonNull @Override public String toString() { diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java index 6163d8099b8c..bc099e3a3b9d 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java @@ -289,11 +289,11 @@ public class LayoutComponent extends Component { } @Override - public void getLocationInWindow(@NonNull float[] value) { + public void getLocationInWindow(@NonNull float[] value, boolean forSelf) { value[0] += mX + mPaddingLeft; value[1] += mY + mPaddingTop; if (mParent != null) { - mParent.getLocationInWindow(value); + mParent.getLocationInWindow(value, false); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java index b0089525af5a..00ec60533087 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java @@ -24,10 +24,13 @@ import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.operations.layout.Component; +import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent; import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure; import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass; import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation; +import java.util.ArrayList; import java.util.List; public class CollapsibleColumnLayout extends ColumnLayout { @@ -153,7 +156,7 @@ public class CollapsibleColumnLayout extends ColumnLayout { } @Override - protected boolean hasVerticalIntrinsicDimension() { + public boolean hasVerticalIntrinsicDimension() { return true; } @@ -166,25 +169,72 @@ public class CollapsibleColumnLayout extends ColumnLayout { boolean verticalWrap, @NonNull MeasurePass measure, @NonNull Size size) { + computeVisibleChildren( + context, maxWidth, maxHeight, horizontalWrap, verticalWrap, measure, size); + } + + @Override + public void computeSize( + @NonNull PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + @NonNull MeasurePass measure) { + computeVisibleChildren(context, maxWidth, maxHeight, false, false, measure, null); + } + + @Override + public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) { + // if needed, take care of weight calculations + super.internalLayoutMeasure(context, measure); + // Check again for visibility + ComponentMeasure m = measure.get(this); + computeVisibleChildren(context, m.getW(), m.getH(), false, false, measure, null); + } + + private void computeVisibleChildren( + @NonNull PaintContext context, + float maxWidth, + float maxHeight, + boolean horizontalWrap, + boolean verticalWrap, + @NonNull MeasurePass measure, + @Nullable Size size) { int visibleChildren = 0; ComponentMeasure self = measure.get(this); self.addVisibilityOverride(Visibility.OVERRIDE_VISIBLE); float currentMaxHeight = maxHeight; + boolean hasPriorities = false; for (Component c : mChildrenComponents) { - if (c instanceof CollapsibleColumnLayout) { - c.measure(context, 0f, maxWidth, 0f, currentMaxHeight, measure); - } else { - c.measure(context, 0f, maxWidth, 0f, Float.MAX_VALUE, measure); + if (!measure.contains(c.getComponentId())) { + // No need to remeasure here if already done + if (c instanceof CollapsibleColumnLayout) { + c.measure(context, 0f, maxWidth, 0f, currentMaxHeight, measure); + } else { + c.measure(context, 0f, maxWidth, 0f, Float.MAX_VALUE, measure); + } } + ComponentMeasure m = measure.get(c); if (!m.isGone()) { - size.setWidth(Math.max(size.getWidth(), m.getW())); - size.setHeight(size.getHeight() + m.getH()); + if (size != null) { + size.setWidth(Math.max(size.getWidth(), m.getW())); + size.setHeight(size.getHeight() + m.getH()); + } visibleChildren++; currentMaxHeight -= m.getH(); } + if (c instanceof LayoutComponent) { + LayoutComponent lc = (LayoutComponent) c; + CollapsiblePriorityModifierOperation priority = + lc.selfOrModifier(CollapsiblePriorityModifierOperation.class); + if (priority != null) { + hasPriorities = true; + } + } } - if (!mChildrenComponents.isEmpty()) { + if (!mChildrenComponents.isEmpty() && size != null) { size.setHeight(size.getHeight() + (mSpacedBy * (visibleChildren - 1))); } @@ -192,7 +242,14 @@ public class CollapsibleColumnLayout extends ColumnLayout { float childrenHeight = 0f; boolean overflow = false; - for (Component child : mChildrenComponents) { + ArrayList<Component> children = mChildrenComponents; + if (hasPriorities) { + // TODO: We need to cache this. + children = + CollapsiblePriority.sortWithPriorities( + mChildrenComponents, CollapsiblePriority.VERTICAL); + } + for (Component child : children) { ComponentMeasure childMeasure = measure.get(child); if (overflow || childMeasure.isGone()) { childMeasure.addVisibilityOverride(Visibility.OVERRIDE_GONE); @@ -209,10 +266,10 @@ public class CollapsibleColumnLayout extends ColumnLayout { visibleChildren++; } } - if (verticalWrap) { + if (verticalWrap && size != null) { size.setHeight(Math.min(maxHeight, childrenHeight)); } - if (visibleChildren == 0 || size.getHeight() <= 0f) { + if (visibleChildren == 0 || (size != null && size.getHeight() <= 0f)) { self.addVisibilityOverride(Visibility.OVERRIDE_GONE); } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsiblePriority.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsiblePriority.java new file mode 100644 index 000000000000..46cd45ecba8a --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsiblePriority.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2025 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.widget.remotecompose.core.operations.layout.managers; + +import com.android.internal.widget.remotecompose.core.operations.layout.Component; +import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation; + +import java.util.ArrayList; + +/** Utility class to manage collapsible priorities on components */ +public class CollapsiblePriority { + + public static final int HORIZONTAL = 0; + public static final int VERTICAL = 1; + + /** + * Returns the priority of a child component + * + * @param c the child component + * @return priority value, or 0f if not found + */ + static float getPriority(Component c, int orientation) { + if (c instanceof LayoutComponent) { + LayoutComponent lc = (LayoutComponent) c; + CollapsiblePriorityModifierOperation priority = + lc.selfOrModifier(CollapsiblePriorityModifierOperation.class); + if (priority != null && priority.getOrientation() == orientation) { + return priority.getPriority(); + } + } + return Float.MAX_VALUE; + } + + /** + * Allocate and return a sorted array of components by their priorities + * + * @param components the children components + * @return list of components sorted by their priority in decreasing order + */ + static ArrayList<Component> sortWithPriorities( + ArrayList<Component> components, int orientation) { + ArrayList<Component> sorted = new ArrayList<>(components); + sorted.sort( + (t1, t2) -> { + float p1 = getPriority(t1, orientation); + float p2 = getPriority(t2, orientation); + return (int) (p2 - p1); + }); + return sorted; + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java index 05f332960c16..e3632f9888ec 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java @@ -24,10 +24,13 @@ import com.android.internal.widget.remotecompose.core.PaintContext; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.WireBuffer; import com.android.internal.widget.remotecompose.core.operations.layout.Component; +import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent; import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure; import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass; import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation; +import java.util.ArrayList; import java.util.List; public class CollapsibleRowLayout extends RowLayout { @@ -135,8 +138,12 @@ public class CollapsibleRowLayout extends RowLayout { } @Override - protected boolean hasHorizontalIntrinsicDimension() { - return true; + public float minIntrinsicHeight(@NonNull RemoteContext context) { + float height = computeModifierDefinedHeight(context); + if (!mChildrenComponents.isEmpty()) { + height += mChildrenComponents.get(0).minIntrinsicHeight(context); + } + return height; } @Override @@ -149,12 +156,8 @@ public class CollapsibleRowLayout extends RowLayout { } @Override - public float minIntrinsicHeight(@NonNull RemoteContext context) { - float height = computeModifierDefinedHeight(context); - if (!mChildrenComponents.isEmpty()) { - height += mChildrenComponents.get(0).minIntrinsicHeight(context); - } - return height; + public boolean hasHorizontalIntrinsicDimension() { + return true; } @Override @@ -166,45 +169,107 @@ public class CollapsibleRowLayout extends RowLayout { boolean verticalWrap, @NonNull MeasurePass measure, @NonNull Size size) { - super.computeWrapSize( - context, Float.MAX_VALUE, maxHeight, horizontalWrap, verticalWrap, measure, size); + computeVisibleChildren( + context, maxWidth, maxHeight, horizontalWrap, verticalWrap, measure, size); } @Override - public boolean applyVisibility( - float selfWidth, float selfHeight, @NonNull MeasurePass measure) { - float childrenWidth = 0f; - float childrenHeight = 0f; - boolean changedVisibility = false; + public void computeSize( + @NonNull PaintContext context, + float minWidth, + float maxWidth, + float minHeight, + float maxHeight, + @NonNull MeasurePass measure) { + computeVisibleChildren(context, maxWidth, maxHeight, false, false, measure, null); + } + + @Override + public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) { + // if needed, take care of weight calculations + super.internalLayoutMeasure(context, measure); + // Check again for visibility + ComponentMeasure m = measure.get(this); + computeVisibleChildren(context, m.getW(), m.getH(), false, false, measure, null); + } + + private void computeVisibleChildren( + @NonNull PaintContext context, + float maxWidth, + float maxHeight, + boolean horizontalWrap, + boolean verticalWrap, + @NonNull MeasurePass measure, + @Nullable Size size) { int visibleChildren = 0; ComponentMeasure self = measure.get(this); - self.clearVisibilityOverride(); - if (selfWidth <= 0 || selfHeight <= 0) { - self.addVisibilityOverride(Visibility.OVERRIDE_GONE); - return true; + self.addVisibilityOverride(Visibility.OVERRIDE_VISIBLE); + float currentMaxWidth = maxWidth; + boolean hasPriorities = false; + for (Component c : mChildrenComponents) { + if (!measure.contains(c.getComponentId())) { + // No need to remeasure here if already done + if (c instanceof CollapsibleRowLayout) { + c.measure(context, 0f, currentMaxWidth, 0f, maxHeight, measure); + } else { + c.measure(context, 0f, Float.MAX_VALUE, 0f, maxHeight, measure); + } + } + ComponentMeasure m = measure.get(c); + if (!m.isGone()) { + if (size != null) { + size.setHeight(Math.max(size.getHeight(), m.getH())); + size.setWidth(size.getWidth() + m.getW()); + } + visibleChildren++; + currentMaxWidth -= m.getW(); + } + if (c instanceof LayoutComponent) { + LayoutComponent lc = (LayoutComponent) c; + CollapsiblePriorityModifierOperation priority = + lc.selfOrModifier(CollapsiblePriorityModifierOperation.class); + if (priority != null) { + hasPriorities = true; + } + } + } + if (!mChildrenComponents.isEmpty() && size != null) { + size.setWidth(size.getWidth() + (mSpacedBy * (visibleChildren - 1))); } - for (Component child : mChildrenComponents) { + + float childrenWidth = 0f; + float childrenHeight = 0f; + + boolean overflow = false; + ArrayList<Component> children = mChildrenComponents; + if (hasPriorities) { + // TODO: We need to cache this. + children = + CollapsiblePriority.sortWithPriorities( + mChildrenComponents, CollapsiblePriority.HORIZONTAL); + } + for (Component child : children) { ComponentMeasure childMeasure = measure.get(child); - int visibility = childMeasure.getVisibility(); - childMeasure.clearVisibilityOverride(); - if (!childMeasure.isVisible()) { + if (overflow || childMeasure.isGone()) { + childMeasure.addVisibilityOverride(Visibility.OVERRIDE_GONE); continue; } - if (childrenWidth + childMeasure.getW() > selfWidth - && childrenHeight + childMeasure.getH() > selfHeight) { + float childWidth = childMeasure.getW(); + boolean childDoesNotFits = childrenWidth + childWidth > maxWidth; + if (childDoesNotFits) { childMeasure.addVisibilityOverride(Visibility.OVERRIDE_GONE); - if (visibility != childMeasure.getVisibility()) { - changedVisibility = true; - } + overflow = true; } else { - childrenWidth += childMeasure.getW(); + childrenWidth += childWidth; childrenHeight = Math.max(childrenHeight, childMeasure.getH()); visibleChildren++; } } - if (visibleChildren == 0) { + if (horizontalWrap && size != null) { + size.setWidth(Math.min(maxWidth, childrenWidth)); + } + if (visibleChildren == 0 || (size != null && size.getWidth() <= 0f)) { self.addVisibilityOverride(Visibility.OVERRIDE_GONE); } - return changedVisibility; } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java index cda90c2d3b0b..9566242ccbc5 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java @@ -33,6 +33,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.measure. import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass; import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightInModifierOperation; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.utils.DebugLog; import com.android.internal.widget.remotecompose.core.serialize.MapSerializer; @@ -372,6 +373,17 @@ public class ColumnLayout extends LayoutManager { DebugLog.e(); } + @Override + public void getLocationInWindow(@NonNull float[] value, boolean forSelf) { + super.getLocationInWindow(value, forSelf); + + if (!forSelf && mVerticalScrollDelegate instanceof ScrollModifierOperation) { + ScrollModifierOperation smo = (ScrollModifierOperation) mVerticalScrollDelegate; + + value[1] += smo.getScrollY(); + } + } + /** * The name of the class * diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java index 5b66b95cf1dd..eb10ead34781 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java @@ -226,9 +226,17 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl measure, mCachedWrapSize); float w = mCachedWrapSize.getWidth(); - computeSize(context, 0f, w, 0, measuredHeight, measure); if (hasHorizontalScroll()) { + computeSize(context, 0f, w, 0, measuredHeight, measure); mComponentModifiers.setHorizontalScrollDimension(measuredWidth, w); + } else { + computeSize( + context, + 0f, + Math.min(measuredWidth, insetMaxWidth), + 0, + Math.min(measuredHeight, insetMaxHeight), + measure); } } else if (hasVerticalIntrinsicDimension()) { mCachedWrapSize.setWidth(0f); @@ -236,9 +244,17 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl computeWrapSize( context, maxWidth, Float.MAX_VALUE, false, false, measure, mCachedWrapSize); float h = mCachedWrapSize.getHeight(); - computeSize(context, 0f, measuredWidth, 0, h, measure); if (hasVerticalScroll()) { + computeSize(context, 0f, measuredWidth, 0, h, measure); mComponentModifiers.setVerticalScrollDimension(measuredHeight, h); + } else { + computeSize( + context, + 0f, + Math.min(measuredWidth, insetMaxWidth), + 0, + Math.min(measuredHeight, insetMaxHeight), + measure); } } else { float maxChildWidth = measuredWidth - mPaddingLeft - mPaddingRight; diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java index d5d2e03c3f2a..15b54a3ce994 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java @@ -32,6 +32,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.LayoutCo import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure; import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass; import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size; +import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthInModifierOperation; import com.android.internal.widget.remotecompose.core.operations.layout.utils.DebugLog; import com.android.internal.widget.remotecompose.core.serialize.MapSerializer; @@ -386,6 +387,17 @@ public class RowLayout extends LayoutManager { DebugLog.e(); } + @Override + public void getLocationInWindow(@NonNull float[] value, boolean forSelf) { + super.getLocationInWindow(value, forSelf); + + if (!forSelf && mHorizontalScrollDelegate instanceof ScrollModifierOperation) { + ScrollModifierOperation smo = (ScrollModifierOperation) mHorizontalScrollDelegate; + + value[0] += smo.getScrollX(); + } + } + /** * The name of the class * diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java index d383ee9e4fc9..120c740eccda 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java @@ -77,6 +77,7 @@ public class TextLayout extends LayoutManager implements VariableSupport, Access private final Size mCachedSize = new Size(0f, 0f); @Nullable private String mCachedString = ""; + @Nullable private String mNewString; Platform.ComputedTextLayout mComputedTextLayout; @@ -99,7 +100,7 @@ public class TextLayout extends LayoutManager implements VariableSupport, Access if (cachedString != null && cachedString.equalsIgnoreCase(mCachedString)) { return; } - mCachedString = cachedString; + mNewString = cachedString; if (mType == -1) { if (mFontFamilyId != -1) { String fontFamily = context.getText(mFontFamilyId); @@ -119,8 +120,6 @@ public class TextLayout extends LayoutManager implements VariableSupport, Access mType = 0; } } - mTextW = -1; - mTextH = -1; if (mHorizontalScrollDelegate != null) { mHorizontalScrollDelegate.reset(); @@ -351,6 +350,9 @@ public class TextLayout extends LayoutManager implements VariableSupport, Access mPaint.setColor(mColor); context.replacePaint(mPaint); float[] bounds = new float[4]; + if (mNewString != null && !mNewString.equals(mCachedString)) { + mCachedString = mNewString; + } if (mCachedString == null) { return; } diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/CollapsiblePriorityModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/CollapsiblePriorityModifierOperation.java new file mode 100644 index 000000000000..b1f2d2d35b93 --- /dev/null +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/CollapsiblePriorityModifierOperation.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2025 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.widget.remotecompose.core.operations.layout.modifiers; + +import android.annotation.NonNull; + +import com.android.internal.widget.remotecompose.core.Operation; +import com.android.internal.widget.remotecompose.core.Operations; +import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.WireBuffer; +import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder; +import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation; +import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer; +import com.android.internal.widget.remotecompose.core.serialize.MapSerializer; +import com.android.internal.widget.remotecompose.core.serialize.Serializable; +import com.android.internal.widget.remotecompose.core.serialize.SerializeTags; + +import java.util.List; + +/** Set an optional priority on a component within a collapsible layout */ +public class CollapsiblePriorityModifierOperation extends Operation + implements ModifierOperation, Serializable { + private static final int OP_CODE = Operations.MODIFIER_COLLAPSIBLE_PRIORITY; + public static final String CLASS_NAME = "CollapsiblePriorityModifierOperation"; + + private float mPriority; + private int mOrientation; + + public CollapsiblePriorityModifierOperation(int orientation, float priority) { + mOrientation = orientation; + mPriority = priority; + } + + public float getPriority() { + return mPriority; + } + + public int getOrientation() { + return mOrientation; + } + + @Override + public void write(@NonNull WireBuffer buffer) { + apply(buffer, mOrientation, mPriority); + } + + @Override + public void apply(@NonNull RemoteContext context) { + // nothing + } + + @NonNull + @Override + public String deepToString(@NonNull String indent) { + return ""; + } + + /** + * Read this operation and add it to the list of operations + * + * @param buffer the buffer to read + * @param operations the list of operations that will be added to + */ + public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) { + int orientation = buffer.readInt(); + float priority = buffer.readFloat(); + operations.add(new CollapsiblePriorityModifierOperation(orientation, priority)); + } + + /** + * The OP_CODE for this command + * + * @return the opcode + */ + public static int id() { + return OP_CODE; + } + + /** + * The name of the class + * + * @return the name + */ + @NonNull + public static String name() { + return CLASS_NAME; + } + + /** + * Populate the documentation with a description of this operation + * + * @param doc to append the description to. + */ + public static void documentation(@NonNull DocumentationBuilder doc) { + doc.operation("Layout Operations", OP_CODE, "CollapsiblePriorityModifier") + .description("Add additional priority to children of Collapsible layouts") + .field(DocumentedOperation.INT, "orientation", "Horizontal(0) or Vertical (1)") + .field(DocumentedOperation.FLOAT, "priority", "The associated priority"); + } + + /** + * Writes out the CollapsiblePriorityModifier to the buffer + * + * @param buffer buffer to write to + * @param priority priority value + * @param orientation orientation (HORIZONTAL or VERTICAL) + */ + public static void apply(@NonNull WireBuffer buffer, int orientation, float priority) { + buffer.start(OP_CODE); + buffer.writeInt(orientation); + buffer.writeFloat(priority); + } + + @Override + public void serialize(MapSerializer serializer) { + serializer + .addTags(SerializeTags.MODIFIER) + .addType(name()) + .add("orientation", mOrientation) + .add("priority", mPriority); + } + + @Override + public void serializeToString(int indent, @NonNull StringSerializer serializer) { + serializer.append(indent, "PRIORITY = [" + getPriority() + "] (" + mOrientation + ")"); + } +} diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java index 3e1f32de66e4..42692f95fcda 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java @@ -430,9 +430,35 @@ public class ScrollModifierOperation extends ListActionsOperation } @Override - public boolean showOnScreen(RemoteContext context, int childId) { - // TODO correct this when we trust the bounds in parent - return scrollByOffset(context, -1000) != 0; + public boolean scrollDirection(RemoteContext context, ScrollDirection direction) { + float offset = mHostDimension * 0.7f; + + if (direction == ScrollDirection.FORWARD + || direction == ScrollDirection.DOWN + || direction == ScrollDirection.RIGHT) { + offset *= -1; + } + + return scrollByOffset(context, (int) offset) != 0; + } + + @Override + public boolean showOnScreen(RemoteContext context, Component child) { + float[] locationInWindow = new float[2]; + child.getLocationInWindow(locationInWindow); + + int offset = 0; + if (handlesVerticalScroll()) { + offset = (int) -locationInWindow[1]; + } else { + offset = (int) -locationInWindow[0]; + } + + if (offset == 0) { + return true; + } else { + return scrollByOffset(context, offset) != 0; + } } @Nullable diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java index a95a175d0edd..120c7ac9efbf 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java +++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java @@ -35,7 +35,10 @@ public class StringUtils { @NonNull public static String floatToString( float value, int beforeDecimalPoint, int afterDecimalPoint, char pre, char post) { - + boolean isNeg = value < 0; + if (isNeg) { + value = -value; + } int integerPart = (int) value; float fractionalPart = value % 1; @@ -54,14 +57,13 @@ public class StringUtils { integerPartString = integerPartString.substring(iLen - beforeDecimalPoint); } if (afterDecimalPoint == 0) { - return integerPartString; + return ((isNeg) ? "-" : "") + integerPartString; } // Convert fractional part to string and pad with zeros for (int i = 0; i < afterDecimalPoint; i++) { fractionalPart *= 10; } - fractionalPart = Math.round(fractionalPart); for (int i = 0; i < afterDecimalPoint; i++) { @@ -87,6 +89,6 @@ public class StringUtils { fact = fact + new String(c); } - return integerPartString + "." + fact; + return ((isNeg) ? "-" : "") + integerPartString + "." + fact; } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java b/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java index 3d1bd12357c9..1610e6332c1c 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java +++ b/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java @@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.core.semantics; import android.annotation.Nullable; import com.android.internal.widget.remotecompose.core.RemoteContext; +import com.android.internal.widget.remotecompose.core.operations.layout.Component; /** * Interface for components that support scrolling. @@ -48,13 +49,23 @@ public interface ScrollableComponent extends AccessibilitySemantics { } /** + * Scrolls the content in the specified direction. + * + * @param direction the direction to scroll + * @return whether a scroll was possible + */ + default boolean scrollDirection(RemoteContext context, ScrollDirection direction) { + return false; + } + + /** * Show a child with the given ID on the screen, typically scrolling so it's fully on screen. * - * @param childId The ID of the child to check for visibility. + * @param child The child (including nested) to check for visibility. * @return {@code true} if the child with the given ID could be shown on screen; {@code false} * otherwise. */ - default boolean showOnScreen(RemoteContext context, int childId) { + default boolean showOnScreen(RemoteContext context, Component child) { return false; } @@ -108,4 +119,13 @@ public interface ScrollableComponent extends AccessibilitySemantics { return mCanScrollBackwards; } } + + enum ScrollDirection { + FORWARD, + BACKWARD, + UP, + DOWN, + LEFT, + RIGHT, + } } diff --git a/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java b/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java index 20e94ab5d898..32a0ccc01738 100644 --- a/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java +++ b/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java @@ -49,6 +49,14 @@ public interface MapSerializer { MapSerializer addIntExpressionSrc(String key, int[] value, int mask); /** + * Add a path + * + * @param key The key + * @param path The path + */ + MapSerializer addPath(String key, float[] path); + + /** * Add metadata to this map for filtering by the data format generator. * * @param value A set of tags to add diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java index e1f2924021a4..575a6b2ee518 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java @@ -22,7 +22,6 @@ import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.remotecompose.core.RemoteContext; import com.android.internal.widget.remotecompose.core.TouchListener; import com.android.internal.widget.remotecompose.core.VariableSupport; @@ -43,7 +42,6 @@ import java.util.HashMap; * * <p>This is used to play the RemoteCompose operations on Android. */ -@VisibleForTesting public class AndroidRemoteContext extends RemoteContext { public void useCanvas(Canvas canvas) { diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java index 0bc99abc17bc..17f4fc82af5f 100644 --- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java +++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java @@ -102,6 +102,7 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta mDocument = value; mDocument.initializeContext(mARContext); mDisable = false; + mARContext.setDocLoadTime(); mARContext.setAnimationEnabled(true); mARContext.setDensity(mDensity); mARContext.setUseChoreographer(true); diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 748c5b48534f..bfa0aa9638a9 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -31,6 +31,7 @@ cc_library_shared_for_libandroid_runtime { name: "libandroid_runtime", host_supported: true, cflags: [ + "-Wno-cast-function-type-mismatch", "-Wno-unused-parameter", "-Wno-non-virtual-dtor", "-Wno-maybe-uninitialized", diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index dec724b6a7ff..e1b3479c7ed2 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -558,8 +558,7 @@ static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr delete parcel; } -static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr) -{ +static Parcel* parcel_for_marshall(JNIEnv* env, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel == NULL) { return NULL; @@ -577,6 +576,16 @@ static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong na return NULL; } + return parcel; +} + +static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr) +{ + Parcel* parcel = parcel_for_marshall(env, nativePtr); + if (parcel == NULL) { + return NULL; + } + jbyteArray ret = env->NewByteArray(parcel->dataSize()); if (ret != NULL) @@ -592,6 +601,56 @@ static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong na return ret; } +static long ensure_capacity(JNIEnv* env, Parcel* parcel, jint remaining) { + long dataSize = parcel->dataSize(); + if (remaining < dataSize) { + jnihelp::ThrowException(env, "java/nio/BufferOverflowException", "()V"); + return -1; + } + return dataSize; +} + +static int android_os_Parcel_marshall_array(JNIEnv* env, jclass clazz, jlong nativePtr, + jbyteArray data, jint offset, jint remaining) +{ + Parcel* parcel = parcel_for_marshall(env, nativePtr); + if (parcel == NULL) { + return 0; + } + + long data_size = ensure_capacity(env, parcel, remaining); + if (data_size < 0) { + return 0; + } + + jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0); + if (array != NULL) + { + memcpy(array + offset, parcel->data(), data_size); + env->ReleasePrimitiveArrayCritical(data, array, 0); + } + return data_size; +} + +static int android_os_Parcel_marshall_buffer(JNIEnv* env, jclass clazz, jlong nativePtr, + jobject javaBuffer, jint offset, jint remaining) { + Parcel* parcel = parcel_for_marshall(env, nativePtr); + if (parcel == NULL) { + return 0; + } + + long data_size = ensure_capacity(env, parcel, remaining); + if (data_size < 0) { + return 0; + } + + jbyte* buffer = (jbyte*)env->GetDirectBufferAddress(javaBuffer); + if (buffer != NULL) { + memcpy(buffer + offset, parcel->data(), data_size); + } + return data_size; +} + static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr, jbyteArray data, jint offset, jint length) { @@ -613,6 +672,25 @@ static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong native } } +static void android_os_Parcel_unmarshall_buffer(JNIEnv* env, jclass clazz, jlong nativePtr, + jobject javaBuffer, jint offset, jint length) +{ + Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); + if (parcel == NULL || length < 0) { + return; + } + + jbyte* buffer = (jbyte*)env->GetDirectBufferAddress(javaBuffer); + if (buffer) + { + parcel->setDataSize(length); + parcel->setDataPosition(0); + + void* raw = parcel->writeInplace(length); + memcpy(raw, (buffer + offset), length); + } +} + static jint android_os_Parcel_compareData(JNIEnv* env, jclass clazz, jlong thisNativePtr, jlong otherNativePtr) { @@ -911,7 +989,10 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeDestroy", "(J)V", (void*)android_os_Parcel_destroy}, {"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall}, + {"nativeMarshallArray", "(J[BII)I", (void*)android_os_Parcel_marshall_array}, + {"nativeMarshallBuffer", "(JLjava/nio/ByteBuffer;II)I", (void*)android_os_Parcel_marshall_buffer}, {"nativeUnmarshall", "(J[BII)V", (void*)android_os_Parcel_unmarshall}, + {"nativeUnmarshallBuffer", "(JLjava/nio/ByteBuffer;II)V", (void*)android_os_Parcel_unmarshall_buffer}, {"nativeCompareData", "(JJ)I", (void*)android_os_Parcel_compareData}, {"nativeCompareDataInRange", "(JIJII)Z", (void*)android_os_Parcel_compareDataInRange}, {"nativeAppendFrom", "(JJII)V", (void*)android_os_Parcel_appendFrom}, diff --git a/core/jni/android_window_InputTransferToken.cpp b/core/jni/android_window_InputTransferToken.cpp index f92d128c7077..b4efacb6c0ef 100644 --- a/core/jni/android_window_InputTransferToken.cpp +++ b/core/jni/android_window_InputTransferToken.cpp @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code #define LOG_TAG "InputTransferToken" @@ -53,7 +52,7 @@ static jlong nativeCreateFromBinder(JNIEnv* env, jclass clazz, jobject tokenBind } static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jlong nativeObj, jobject parcelObj) { - InputTransferToken* inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj); + auto inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj); Parcel* parcel = parcelForJavaObject(env, parcelObj); inputTransferToken->writeToParcel(parcel); } @@ -67,12 +66,12 @@ static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) } static jobject nativeGetBinderToken(JNIEnv* env, jclass clazz, jlong nativeObj) { - sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj); + auto inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj); return javaObjectForIBinder(env, inputTransferToken->mToken); } static jlong nativeGetBinderTokenRef(JNIEnv*, jclass, jlong nativeObj) { - sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj); + auto inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj); return reinterpret_cast<jlong>(inputTransferToken->mToken.get()); } @@ -105,12 +104,9 @@ static jlong nativeGetNativeInputTransferTokenFinalizer(JNIEnv* env, jclass claz static bool nativeEquals(JNIEnv* env, jclass clazz, jlong inputTransferTokenObj1, jlong inputTransferTokenObj2) { - sp<InputTransferToken> inputTransferToken1( - reinterpret_cast<InputTransferToken*>(inputTransferTokenObj1)); - sp<InputTransferToken> inputTransferToken2( - reinterpret_cast<InputTransferToken*>(inputTransferTokenObj2)); - - return inputTransferToken1 == inputTransferToken2; + auto token1 = reinterpret_cast<InputTransferToken*>(inputTransferTokenObj1); + auto token2 = reinterpret_cast<InputTransferToken*>(inputTransferTokenObj2); + return (token1 != nullptr) && (token2 != nullptr) && (*token1 == *token2); } static const JNINativeMethod sInputTransferTokenMethods[] = { diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp index 7b085b16d24b..ba74b0e8cce5 100644 --- a/core/jni/android_window_ScreenCapture.cpp +++ b/core/jni/android_window_ScreenCapture.cpp @@ -109,27 +109,29 @@ public: return binder::Status::ok(); } captureResults.fenceResult.value()->waitForever(LOG_TAG); - jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer( - env, captureResults.buffer->toAHardwareBuffer()); - jobject jGainmap = nullptr; + auto jhardwareBuffer = ScopedLocalRef<jobject>( + env, android_hardware_HardwareBuffer_createFromAHardwareBuffer( + env, captureResults.buffer->toAHardwareBuffer())); + auto jGainmap = ScopedLocalRef<jobject>(env); if (captureResults.optionalGainMap) { - jGainmap = android_hardware_HardwareBuffer_createFromAHardwareBuffer( - env, captureResults.optionalGainMap->toAHardwareBuffer()); + jGainmap = ScopedLocalRef<jobject>( + env, android_hardware_HardwareBuffer_createFromAHardwareBuffer( + env, captureResults.optionalGainMap->toAHardwareBuffer())); } - jobject screenshotHardwareBuffer = - env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz, + auto screenshotHardwareBuffer = + ScopedLocalRef<jobject>(env, env->CallStaticObjectMethod( + gScreenshotHardwareBufferClassInfo.clazz, gScreenshotHardwareBufferClassInfo.builder, - jhardwareBuffer, + jhardwareBuffer.get(), static_cast<jint>(captureResults.capturedDataspace), captureResults.capturedSecureLayers, - captureResults.capturedHdrLayers, jGainmap, - captureResults.hdrSdrRatio); + captureResults.capturedHdrLayers, jGainmap.get(), + captureResults.hdrSdrRatio)); checkAndClearException(env, "builder"); - env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, screenshotHardwareBuffer, + env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, + screenshotHardwareBuffer.get(), fenceStatus(captureResults.fenceResult)); checkAndClearException(env, "accept"); - env->DeleteLocalRef(jhardwareBuffer); - env->DeleteLocalRef(screenshotHardwareBuffer); return binder::Status::ok(); } diff --git a/core/res/res/color/notification_close_button_state_tint.xml b/core/res/res/color/notification_close_button_state_tint.xml new file mode 100644 index 000000000000..bc42cebbbb2a --- /dev/null +++ b/core/res/res/color/notification_close_button_state_tint.xml @@ -0,0 +1,19 @@ +<!-- + ~ Copyright (C) 2025 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, softwarere + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@color/notification_expand_button_state_tint" /> +</selector>
\ No newline at end of file diff --git a/core/res/res/drawable-w192dp/loader_horizontal_watch.xml b/core/res/res/drawable-w192dp/loader_horizontal_watch.xml new file mode 100644 index 000000000000..18cea6e0d87d --- /dev/null +++ b/core/res/res/drawable-w192dp/loader_horizontal_watch.xml @@ -0,0 +1,97 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="15dp" android:width="67dp" android:viewportHeight="15" android:viewportWidth="67"> + <group android:name="_R_G"> + <group android:name="_R_G_L_1_G" android:translateX="33.5" android:translateY="7.5"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M33.5 -7.5 C33.5,-7.5 33.5,7.5 33.5,7.5 C33.5,7.5 -33.5,7.5 -33.5,7.5 C-33.5,7.5 -33.5,-7.5 -33.5,-7.5 C-33.5,-7.5 33.5,-7.5 33.5,-7.5c "/> + </group> + <group android:name="_R_G_L_0_G" android:translateX="-296.5" android:translateY="-62.5" android:pivotX="330" android:pivotY="70" android:scaleX="0.1" android:scaleY="0.1"> + <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-224.84700000000004" android:translateY="-321.948" android:pivotX="555.09" android:pivotY="-329" android:rotation="28.9" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M194.88 359 C190,359 185.05,357.81 180.48,355.3 C59.86,289.14 -41.55,191.9 -112.79,74.11 C-186.14,-47.16 -224.91,-186.55 -224.91,-329 C-224.91,-345.57 -211.48,-359 -194.91,-359 C-178.34,-359 -164.91,-345.57 -164.91,-329 C-164.91,-197.5 -129.13,-68.84 -61.45,43.06 C4.33,151.82 97.97,241.6 209.33,302.69 C223.86,310.66 229.18,328.9 221.21,343.42 C215.75,353.37 205.48,359 194.88,359c "/> + </group> + <group android:name="_R_G_L_0_G_L_5_G" android:translateX="744.323" android:translateY="-277.96299999999997" android:pivotX="-414.08" android:pivotY="-372.985" android:rotation="28.9"> + <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-335.95 402.99 C-351.13,402.99 -364.16,391.5 -365.76,376.07 C-367.46,359.59 -355.49,344.85 -339.01,343.14 C-162.93,324.91 -0.15,242.33 119.34,110.62 C239.66,-22.01 305.92,-193.76 305.92,-372.98 C305.92,-389.55 319.35,-402.98 335.92,-402.98 C352.49,-402.98 365.92,-389.55 365.92,-372.98 C365.92,-178.82 294.13,7.24 163.78,150.93 C34.34,293.61 -142.03,383.07 -332.83,402.82 C-333.88,402.93 -334.92,402.99 -335.95,402.99c "/> + </group> + <group android:name="_R_G_L_0_G_L_2_G" android:translateX="185.385" android:translateY="70.09100000000001" android:pivotX="144.858" android:pivotY="-721.039" android:rotation="28.9" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M144.62 58.96 C144.61,58.96 144.61,58.96 144.6,58.96 C40.39,58.93 -60.82,38.66 -156.19,-1.28 C-171.48,-7.68 -178.68,-25.26 -172.28,-40.54 C-165.88,-55.82 -148.3,-63.02 -133.02,-56.62 C-45.02,-19.77 48.4,-1.07 144.63,-1.04 C161.19,-1.03 174.62,12.4 174.62,28.97 C174.61,45.53 161.18,58.96 144.62,58.96c "/> + </group> + <group android:name="_R_G_L_0_G_L_0_G" android:translateX="330" android:translateY="70"> + <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-660 -313 C-660,-313 -660,313 -660,313 C-660,313 660,313 660,313 C660,313 660,-313 660,-313 C660,-313 -660,-313 -660,-313c M300.74 -1.16 C205.46,38.62 103.22,59.09 -0.03,59.05 C-103.28,59.01 -205.51,38.48 -300.76,-1.37 C-316.05,-7.76 -323.26,-25.34 -316.86,-40.62 C-310.47,-55.91 -292.9,-63.12 -277.61,-56.72 C-189.68,-19.94 -95.32,-0.98 -0.01,-0.95 C95.3,-0.92 189.67,-19.81 277.63,-56.53 C292.92,-62.91 310.49,-55.69 316.87,-40.4 C323.25,-25.11 316.03,-7.54 300.74,-1.16c "/> + </group> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector> + diff --git a/core/res/res/drawable-w204dp/loader_horizontal_watch.xml b/core/res/res/drawable-w204dp/loader_horizontal_watch.xml new file mode 100644 index 000000000000..fbc6eab320eb --- /dev/null +++ b/core/res/res/drawable-w204dp/loader_horizontal_watch.xml @@ -0,0 +1,104 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="15dp" android:width="70dp" android:viewportHeight="15" android:viewportWidth="70"> + <group android:name="_R_G"> + <group android:name="_R_G_L_1_G" android:translateX="35" android:translateY="7.5"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M35 -7.5 C35,-7.5 35,7.5 35,7.5 C35,7.5 -35,7.5 -35,7.5 C-35,7.5 -35,-7.5 -35,-7.5 C-35,-7.5 35,-7.5 35,-7.5c "/> + </group> + <group android:name="_R_G_L_0_G" android:translateX="-310" android:translateY="-64" android:pivotX="345" android:pivotY="71.5" android:scaleX="0.1" android:scaleY="0.1"> + <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-239.44799999999998" android:translateY="-341.45" android:pivotX="584.448" android:pivotY="-346.55" android:rotation="28.8" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M205.28 376.55 C200.4,376.55 195.46,375.36 190.88,372.85 C64.08,303.29 -42.54,201.07 -117.44,77.24 C-194.55,-50.25 -235.31,-196.79 -235.31,-346.55 C-235.31,-363.12 -221.88,-376.55 -205.31,-376.55 C-188.74,-376.55 -175.31,-363.12 -175.31,-346.55 C-175.31,-207.74 -137.54,-71.93 -66.1,46.19 C3.34,160.99 102.18,255.76 219.73,320.24 C234.26,328.21 239.58,346.45 231.61,360.97 C226.15,370.92 215.88,376.55 205.28,376.55c "/> + </group> + <group android:name="_R_G_L_0_G_L_5_G" android:translateX="781.413" android:translateY="-295.124" android:pivotX="-436.413" android:pivotY="-392.876" android:rotation="28.8"> + <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-353.86 422.88 C-369.04,422.88 -382.07,411.4 -383.67,395.97 C-385.37,379.49 -373.4,364.74 -356.92,363.03 C-171.06,343.79 0.76,256.62 126.89,117.59 C253.89,-22.41 323.83,-203.7 323.83,-392.88 C323.83,-409.44 337.26,-422.88 353.83,-422.88 C370.4,-422.88 383.83,-409.44 383.83,-392.88 C383.83,-188.76 308.36,6.84 171.32,157.9 C35.25,307.89 -150.15,401.94 -350.74,422.72 C-351.79,422.82 -352.83,422.88 -353.86,422.88c "/> + </group> + <group android:name="_R_G_L_0_G_L_2_G" android:translateX="192.671" android:translateY="71.49599999999998" android:pivotX="152.329" android:pivotY="-759.496" android:rotation="28.8" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M152.33 60.5 C152.33,60.5 152.32,60.5 152.32,60.5 C42.76,60.47 -63.64,39.16 -163.91,-2.82 C-179.19,-9.22 -186.39,-26.8 -179.99,-42.08 C-173.59,-57.36 -156.02,-64.57 -140.73,-58.16 C-47.84,-19.27 50.77,0.47 152.34,0.5 C168.91,0.51 182.33,13.94 182.33,30.51 C182.32,47.08 168.89,60.5 152.33,60.5c "/> + </group> + <group android:name="_R_G_L_0_G_L_0_G" android:translateX="345" android:translateY="71.5"> + <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-579 -259.5 C-579,-259.5 -579,259.5 -579,259.5 C-579,259.5 579,259.5 579,259.5 C579,259.5 579,-259.5 579,-259.5 C579,-259.5 -579,-259.5 -579,-259.5c M316.17 -2.8 C216,39.02 108.52,60.54 -0.03,60.5 C-108.58,60.46 -216.04,38.87 -316.18,-3.02 C-331.47,-9.41 -338.68,-26.99 -332.28,-42.27 C-325.89,-57.56 -308.32,-64.76 -293.03,-58.37 C-200.22,-19.55 -100.61,0.46 -0.01,0.5 C100.6,0.54 200.22,-19.41 293.06,-58.17 C308.35,-64.55 325.92,-57.33 332.3,-42.04 C338.68,-26.75 331.46,-9.18 316.17,-2.8c "/> + </group> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector> + diff --git a/core/res/res/drawable-w216dp/loader_horizontal_watch.xml b/core/res/res/drawable-w216dp/loader_horizontal_watch.xml new file mode 100644 index 000000000000..ed4b7ea0ff02 --- /dev/null +++ b/core/res/res/drawable-w216dp/loader_horizontal_watch.xml @@ -0,0 +1,105 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="16dp" android:width="74dp" android:viewportHeight="16" android:viewportWidth="74"> + <group android:name="_R_G"> + <group android:name="_R_G_L_1_G" android:translateX="37" android:translateY="8"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M37 -8 C37,-8 37,8 37,8 C37,8 -37,8 -37,8 C-37,8 -37,-8 -37,-8 C-37,-8 37,-8 37,-8c "/> + </group> + <group android:name="_R_G_L_0_G" android:translateX="-328" android:translateY="-65.5" android:pivotX="365" android:pivotY="73.5" android:scaleX="0.1" android:scaleY="0.1"> + <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-256.447" android:translateY="-365.014" android:pivotX="621.447" android:pivotY="-368.486" android:rotation="28.8" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M218.28 398.49 C213.4,398.49 208.46,397.3 203.88,394.78 C69.34,320.99 -43.78,212.53 -123.25,81.15 C-205.06,-54.11 -248.31,-209.59 -248.31,-368.49 C-248.31,-385.05 -234.88,-398.49 -218.31,-398.49 C-201.74,-398.49 -188.31,-385.05 -188.31,-368.49 C-188.31,-220.54 -148.06,-75.8 -71.91,50.09 C2.1,172.45 107.45,273.45 232.73,342.18 C247.26,350.15 252.58,368.38 244.61,382.91 C239.15,392.86 228.88,398.49 218.28,398.49c "/> + </group> + <group android:name="_R_G_L_0_G_L_5_G" android:translateX="829.0260000000001" android:translateY="-315.759" android:pivotX="-464.026" android:pivotY="-417.741" android:rotation="28.8"> + <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-376.25 447.74 C-391.43,447.74 -404.46,436.26 -406.05,420.83 C-407.76,404.35 -395.78,389.61 -379.3,387.9 C-181.22,367.38 1.9,274.48 136.32,126.3 C271.67,-22.9 346.22,-216.12 346.22,-417.74 C346.22,-434.31 359.65,-447.74 376.22,-447.74 C392.79,-447.74 406.22,-434.31 406.22,-417.74 C406.22,-201.18 326.15,6.35 180.76,166.61 C36.39,325.75 -160.31,425.54 -373.12,447.58 C-374.17,447.69 -375.22,447.74 -376.25,447.74c "/> + </group> + <group android:name="_R_G_L_0_G_L_2_G" android:translateX="203.029" android:translateY="74.06899999999996" android:pivotX="161.971" android:pivotY="-807.569" android:rotation="28.8" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M161.97 62.43 C161.97,62.43 161.96,62.43 161.96,62.43 C45.71,62.4 -67.17,39.79 -173.55,-4.75 C-188.83,-11.15 -196.03,-28.72 -189.63,-44.01 C-183.24,-59.29 -165.66,-66.49 -150.38,-60.09 C-51.37,-18.64 53.72,2.4 161.98,2.43 C178.55,2.44 191.98,15.87 191.97,32.44 C191.97,49 178.54,62.43 161.97,62.43c "/> + </group> + <group android:name="_R_G_L_0_G_L_0_G" android:translateX="365" android:translateY="73.5"> + <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-609 -244.5 C-609,-244.5 -609,244.5 -609,244.5 C-609,244.5 609,244.5 609,244.5 C609,244.5 609,-244.5 609,-244.5 C609,-244.5 -609,-244.5 -609,-244.5c M335.44 -4.16 C229.17,40.21 115.13,63.04 -0.04,63 C-115.21,62.96 -229.22,40.05 -335.47,-4.39 C-350.76,-10.79 -357.95,-28.36 -351.56,-43.65 C-345.17,-58.93 -327.59,-66.14 -312.31,-59.74 C-213.39,-18.36 -107.24,2.96 -0.02,3 C107.21,3.04 213.38,-18.22 312.33,-59.53 C327.62,-65.91 345.19,-58.69 351.57,-43.4 C357.95,-28.11 350.73,-10.54 335.44,-4.16c "/> + </group> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector> + + diff --git a/core/res/res/drawable-w228dp/loader_horizontal_watch.xml b/core/res/res/drawable-w228dp/loader_horizontal_watch.xml new file mode 100644 index 000000000000..c4574d8af46c --- /dev/null +++ b/core/res/res/drawable-w228dp/loader_horizontal_watch.xml @@ -0,0 +1,103 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="16dp" android:width="78dp" android:viewportHeight="16" android:viewportWidth="78"> + <group android:name="_R_G"> + <group android:name="_R_G_L_1_G" android:translateX="39" android:translateY="8"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M39 -8 C39,-8 39,8 39,8 C39,8 -39,8 -39,8 C-39,8 -39,-8 -39,-8 C-39,-8 39,-8 39,-8c "/> + </group> + <group android:name="_R_G_L_0_G" android:translateX="-345" android:translateY="-67" android:pivotX="384" android:pivotY="75" android:scaleX="0.1" android:scaleY="0.1"> + <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-274.19" android:translateY="-390.077" android:pivotX="658.448" android:pivotY="-390.423" android:rotation="28.7" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M231.28 420.42 C226.4,420.42 221.45,419.23 216.88,416.72 C74.61,338.68 -45.02,224 -129.06,85.06 C-171.54,14.82 -204.38,-60.73 -226.66,-139.5 C-249.65,-220.76 -261.31,-305.18 -261.31,-390.42 C-261.31,-406.99 -247.88,-420.42 -231.31,-420.42 C-214.74,-420.42 -201.31,-406.99 -201.31,-390.42 C-201.31,-310.71 -190.42,-231.78 -168.93,-155.83 C-148.11,-82.23 -117.42,-11.63 -77.72,54 C0.86,183.92 112.71,291.15 245.73,364.12 C260.26,372.08 265.58,390.32 257.61,404.85 C252.15,414.79 241.88,420.42 231.28,420.42c "/> + </group> + <group android:name="_R_G_L_0_G_L_5_G" android:translateX="875.8979999999999" android:translateY="-337.894" android:pivotX="-491.64" android:pivotY="-442.606" android:rotation="28.7"> + <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-398.64 472.61 C-413.82,472.61 -426.84,461.13 -428.44,445.7 C-430.15,429.22 -418.17,414.47 -401.69,412.77 C-191.38,390.98 3.04,292.33 145.75,135.01 C289.46,-23.4 368.6,-228.54 368.6,-442.61 C368.6,-459.17 382.04,-472.61 398.6,-472.61 C415.17,-472.61 428.6,-459.17 428.6,-442.61 C428.6,-213.6 343.93,5.85 190.19,175.33 C37.53,343.61 -170.48,449.13 -395.51,472.44 C-396.56,472.55 -397.6,472.61 -398.64,472.61c "/> + </group> + <group android:name="_R_G_L_0_G_L_2_G" android:translateX="212.64499999999998" android:translateY="75.14200000000005" android:pivotX="171.613" android:pivotY="-855.642" android:rotation="28.7" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M171.61 64.36 C171.61,64.36 171.61,64.36 171.61,64.36 C48.68,64.32 -70.7,40.42 -183.19,-6.68 C-198.47,-13.07 -205.68,-30.65 -199.28,-45.93 C-192.88,-61.22 -175.3,-68.42 -160.02,-62.02 C-54.9,-18.01 56.68,4.33 171.62,4.36 C188.19,4.36 201.62,17.8 201.61,34.36 C201.61,50.93 188.18,64.36 171.61,64.36c "/> + </group> + <group android:name="_R_G_L_0_G_L_0_G" android:translateX="384" android:translateY="75"> + <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-611 -259 C-611,-259 -611,259 -611,259 C-611,259 611,259 611,259 C611,259 611,-259 611,-259 C611,-259 -611,-259 -611,-259c M354.66 -6.52 C242.36,40.4 121.76,64.54 -0.04,64.5 C-121.84,64.46 -242.44,40.23 -354.74,-6.76 C-370.04,-13.16 -377.24,-30.73 -370.84,-46.02 C-364.44,-61.3 -346.94,-68.51 -331.64,-62.12 C-226.54,-18.18 -113.84,4.46 -0.04,4.5 C113.76,4.54 226.56,-18.02 331.56,-61.89 C346.86,-68.27 364.46,-61.05 370.86,-45.76 C377.26,-30.47 369.96,-12.9 354.66,-6.52c "/> + </group> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector> diff --git a/core/res/res/drawable-w240dp/loader_horizontal_watch.xml b/core/res/res/drawable-w240dp/loader_horizontal_watch.xml new file mode 100644 index 000000000000..ad60bbdc420c --- /dev/null +++ b/core/res/res/drawable-w240dp/loader_horizontal_watch.xml @@ -0,0 +1,104 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="17dp" android:width="82dp" android:viewportHeight="17" android:viewportWidth="82"> + <group android:name="_R_G"> + <group android:name="_R_G_L_1_G" android:translateX="41" android:translateY="8.5"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M41 -8.5 C41,-8.5 41,8.5 41,8.5 C41,8.5 -41,8.5 -41,8.5 C-41,8.5 -41,-8.5 -41,-8.5 C-41,-8.5 41,-8.5 41,-8.5c "/> + </group> + <group android:name="_R_G_L_0_G" android:translateX="-362.5" android:translateY="-69" android:pivotX="403.5" android:pivotY="77.5" android:scaleX="0.1" android:scaleY="0.1"> + <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-291.64799999999997" android:translateY="-414.141" android:pivotX="695.448" android:pivotY="-412.359" android:rotation="28.7" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M244.28 442.36 C239.4,442.36 234.45,441.17 229.88,438.66 C79.87,356.38 -46.26,235.46 -134.87,88.96 C-179.66,14.91 -214.28,-64.74 -237.78,-147.79 C-262.02,-233.47 -274.31,-322.49 -274.31,-412.36 C-274.31,-428.93 -260.88,-442.36 -244.31,-442.36 C-227.74,-442.36 -214.31,-428.93 -214.31,-412.36 C-214.31,-328.01 -202.78,-244.49 -180.05,-164.12 C-158.01,-86.24 -125.54,-11.54 -83.53,57.91 C-0.38,195.38 117.97,308.85 258.73,386.05 C273.26,394.02 278.58,412.26 270.61,426.78 C265.15,436.73 254.88,442.36 244.28,442.36c "/> + </group> + <group android:name="_R_G_L_0_G_L_5_G" android:translateX="923.0530000000001" android:translateY="-359.029" android:pivotX="-519.253" android:pivotY="-467.471" android:rotation="28.7"> + <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-421.02 497.47 C-436.2,497.47 -449.23,485.99 -450.83,470.56 C-452.53,454.08 -440.56,439.34 -424.08,437.63 C-201.54,414.57 4.18,310.19 155.19,143.73 C229.54,61.77 287.7,-31.75 328.04,-134.22 C369.81,-240.3 390.99,-352.42 390.99,-467.47 C390.99,-484.04 404.42,-497.47 420.99,-497.47 C437.56,-497.47 450.99,-484.04 450.99,-467.47 C450.99,-226.02 361.72,5.35 199.63,184.04 C38.67,361.47 -180.63,472.73 -417.89,497.31 C-418.94,497.42 -419.99,497.47 -421.02,497.47c "/> + </group> + <group android:name="_R_G_L_0_G_L_2_G" android:translateX="222.54600000000002" android:translateY="77.21400000000006" android:pivotX="181.254" android:pivotY="-903.714" android:rotation="28.7" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M181.26 66.28 C181.25,66.28 181.25,66.28 181.25,66.28 C51.64,66.25 -74.22,41.06 -192.83,-8.6 C-208.12,-15 -215.32,-32.58 -208.92,-47.86 C-202.52,-63.15 -184.94,-70.35 -169.66,-63.95 C-58.42,-17.38 59.64,6.25 181.26,6.28 C197.83,6.29 211.26,19.72 211.26,36.29 C211.25,52.86 197.82,66.28 181.26,66.28c "/> + </group> + <group android:name="_R_G_L_0_G_L_0_G" android:translateX="403.5" android:translateY="77.5"> + <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-630.5 -255.5 C-630.5,-255.5 -630.5,255.5 -630.5,255.5 C-630.5,255.5 630.5,255.5 630.5,255.5 C630.5,255.5 630.5,-255.5 630.5,-255.5 C630.5,-255.5 -630.5,-255.5 -630.5,-255.5c M374 -8.88 C255.5,40.59 128.4,66.04 0,66 C-128.4,65.95 -255.6,40.42 -374,-9.14 C-389.3,-15.53 -396.5,-33.11 -390.1,-48.39 C-383.7,-63.68 -366.2,-70.88 -350.9,-64.49 C-239.7,-18 -120.5,5.96 0,6 C120.4,6.04 239.7,-17.84 350.9,-64.25 C366.2,-70.63 383.7,-63.41 390.1,-48.12 C396.5,-32.83 389.3,-15.26 374,-8.88c "/> + </group> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector> + diff --git a/core/res/res/drawable/close_button_bg.xml b/core/res/res/drawable/close_button_bg.xml new file mode 100644 index 000000000000..59ac7d403b05 --- /dev/null +++ b/core/res/res/drawable/close_button_bg.xml @@ -0,0 +1,30 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/close_button_pill_colorized_layer"> + <shape xmlns:android="http://schemas.android.com/apk/res/android"> + <corners android:radius="@dimen/notification_close_button_size" /> + <solid android:color="@android:color/white" /> + </shape> + </item> + <item> + <shape xmlns:android="http://schemas.android.com/apk/res/android"> + <corners android:radius="@dimen/notification_close_button_size" /> + <solid android:color="@color/notification_close_button_state_tint" /> + </shape> + </item> +</layer-list>
\ No newline at end of file diff --git a/core/res/res/drawable/loader_horizontal_watch.xml b/core/res/res/drawable/loader_horizontal_watch.xml new file mode 100644 index 000000000000..6b86c634d554 --- /dev/null +++ b/core/res/res/drawable/loader_horizontal_watch.xml @@ -0,0 +1,103 @@ +<!-- + ~ Copyright (C) 2025 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. + --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="14dp" android:width="76dp" android:viewportHeight="14" android:viewportWidth="76"> + <group android:name="_R_G"> + <group android:name="_R_G_L_1_G" android:translateX="39" android:translateY="8"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M39 -8 C39,-8 39,8 39,8 C39,8 -39,8 -39,8 C-39,8 -39,-8 -39,-8 C-39,-8 39,-8 39,-8c "/> + </group> + <group android:name="_R_G_L_0_G" android:translateX="-345" android:translateY="-67" android:pivotX="384" android:pivotY="75" android:scaleX="0.1" android:scaleY="0.1"> + <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-274.19" android:translateY="-390.077" android:pivotX="658.448" android:pivotY="-390.423" android:rotation="28.7" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M231.28 420.42 C226.4,420.42 221.45,419.23 216.88,416.72 C74.61,338.68 -45.02,224 -129.06,85.06 C-171.54,14.82 -204.38,-60.73 -226.66,-139.5 C-249.65,-220.76 -261.31,-305.18 -261.31,-390.42 C-261.31,-406.99 -247.88,-420.42 -231.31,-420.42 C-214.74,-420.42 -201.31,-406.99 -201.31,-390.42 C-201.31,-310.71 -190.42,-231.78 -168.93,-155.83 C-148.11,-82.23 -117.42,-11.63 -77.72,54 C0.86,183.92 112.71,291.15 245.73,364.12 C260.26,372.08 265.58,390.32 257.61,404.85 C252.15,414.79 241.88,420.42 231.28,420.42c "/> + </group> + <group android:name="_R_G_L_0_G_L_5_G" android:translateX="875.8979999999999" android:translateY="-337.894" android:pivotX="-491.64" android:pivotY="-442.606" android:rotation="28.7"> + <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-398.64 472.61 C-413.82,472.61 -426.84,461.13 -428.44,445.7 C-430.15,429.22 -418.17,414.47 -401.69,412.77 C-191.38,390.98 3.04,292.33 145.75,135.01 C289.46,-23.4 368.6,-228.54 368.6,-442.61 C368.6,-459.17 382.04,-472.61 398.6,-472.61 C415.17,-472.61 428.6,-459.17 428.6,-442.61 C428.6,-213.6 343.93,5.85 190.19,175.33 C37.53,343.61 -170.48,449.13 -395.51,472.44 C-396.56,472.55 -397.6,472.61 -398.64,472.61c "/> + </group> + <group android:name="_R_G_L_0_G_L_2_G" android:translateX="212.64499999999998" android:translateY="75.14200000000005" android:pivotX="171.613" android:pivotY="-855.642" android:rotation="28.7" android:scaleY="0"> + <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M171.61 64.36 C171.61,64.36 171.61,64.36 171.61,64.36 C48.68,64.32 -70.7,40.42 -183.19,-6.68 C-198.47,-13.07 -205.68,-30.65 -199.28,-45.93 C-192.88,-61.22 -175.3,-68.42 -160.02,-62.02 C-54.9,-18.01 56.68,4.33 171.62,4.36 C188.19,4.36 201.62,17.8 201.61,34.36 C201.61,50.93 188.18,64.36 171.61,64.36c "/> + </group> + <group android:name="_R_G_L_0_G_L_0_G" android:translateX="384" android:translateY="75"> + <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-611 -259 C-611,-259 -611,259 -611,259 C-611,259 611,259 611,259 C611,259 611,-259 611,-259 C611,-259 -611,-259 -611,-259c M354.66 -6.52 C242.36,40.4 121.76,64.54 -0.04,64.5 C-121.84,64.46 -242.44,40.23 -354.74,-6.76 C-370.04,-13.16 -377.24,-30.73 -370.84,-46.02 C-364.44,-61.3 -346.94,-68.51 -331.64,-62.12 C-226.54,-18.18 -113.84,4.46 -0.04,4.5 C113.76,4.54 226.56,-18.02 331.56,-61.89 C346.86,-68.27 364.46,-61.05 370.86,-45.76 C377.26,-30.47 369.96,-12.9 354.66,-6.52c "/> + </group> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_6_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_5_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_L_2_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector> diff --git a/core/res/res/layout/accessibility_autoclick_type_panel.xml b/core/res/res/layout/accessibility_autoclick_type_panel.xml index 902ef7fc38e8..615af6fb16f8 100644 --- a/core/res/res/layout/accessibility_autoclick_type_panel.xml +++ b/core/res/res/layout/accessibility_autoclick_type_panel.xml @@ -49,7 +49,8 @@ android:id="@+id/accessibility_autoclick_drag_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_drag" - android:src="@drawable/accessibility_autoclick_drag" /> + android:src="@drawable/accessibility_autoclick_drag" + android:clickable="false" /> </LinearLayout> <LinearLayout @@ -60,7 +61,8 @@ android:id="@+id/accessibility_autoclick_double_click_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_double_click" - android:src="@drawable/accessibility_autoclick_double_click" /> + android:src="@drawable/accessibility_autoclick_double_click" + android:clickable="false" /> </LinearLayout> <LinearLayout @@ -71,7 +73,8 @@ android:id="@+id/accessibility_autoclick_right_click_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_right_click" - android:src="@drawable/accessibility_autoclick_right_click" /> + android:src="@drawable/accessibility_autoclick_right_click" + android:clickable="false" /> </LinearLayout> <LinearLayout @@ -82,7 +85,8 @@ android:id="@+id/accessibility_autoclick_scroll_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_scroll" - android:src="@drawable/accessibility_autoclick_scroll" /> + android:src="@drawable/accessibility_autoclick_scroll" + android:clickable="false" /> </LinearLayout> <LinearLayout @@ -93,7 +97,8 @@ android:id="@+id/accessibility_autoclick_left_click_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_left_click" - android:src="@drawable/accessibility_autoclick_left_click" /> + android:src="@drawable/accessibility_autoclick_left_click" + android:clickable="false" /> </LinearLayout> </LinearLayout> @@ -114,7 +119,8 @@ android:id="@+id/accessibility_autoclick_pause_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_pause" - android:src="@drawable/accessibility_autoclick_pause" /> + android:src="@drawable/accessibility_autoclick_pause" + android:clickable="false" /> </LinearLayout> <LinearLayout @@ -125,7 +131,8 @@ android:id="@+id/accessibility_autoclick_position_button" style="@style/AccessibilityAutoclickPanelImageButtonStyle" android:contentDescription="@string/accessibility_autoclick_position" - android:src="@drawable/accessibility_autoclick_position" /> + android:src="@drawable/accessibility_autoclick_position" + android:clickable="false" /> </LinearLayout> </LinearLayout> diff --git a/core/res/res/layout/chooser_az_label_row.xml b/core/res/res/layout/chooser_az_label_row.xml index baf07cec9875..0e907c10b72c 100644 --- a/core/res/res/layout/chooser_az_label_row.xml +++ b/core/res/res/layout/chooser_az_label_row.xml @@ -16,7 +16,7 @@ --> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" - android:contentDescription="@string/chooser_all_apps_button_label" + android:importantForAccessibility="no" android:src="@drawable/chooser_row_layer_list" android:paddingTop="16dp" android:layout_width="match_parent" diff --git a/core/res/res/layout/notification_2025_action_list.xml b/core/res/res/layout/notification_2025_action_list.xml index 053aca068027..6c07ec1a7c7b 100644 --- a/core/res/res/layout/notification_2025_action_list.xml +++ b/core/res/res/layout/notification_2025_action_list.xml @@ -22,6 +22,7 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="@dimen/notification_2025_action_list_margin_bottom" + android:minHeight="@dimen/notification_2025_action_list_min_height" > <LinearLayout diff --git a/core/res/res/layout/notification_2025_conversation_icon_container.xml b/core/res/res/layout/notification_2025_conversation_icon_container.xml index 7ec2450ceb71..16c95009051c 100644 --- a/core/res/res/layout/notification_2025_conversation_icon_container.xml +++ b/core/res/res/layout/notification_2025_conversation_icon_container.xml @@ -29,7 +29,8 @@ <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_margin="@dimen/notification_2025_margin" + android:layout_marginHorizontal="@dimen/notification_2025_margin" + android:layout_marginTop="@dimen/notification_2025_margin" android:clipChildren="false" android:clipToPadding="false" android:layout_gravity="top|center_horizontal" diff --git a/core/res/res/layout/notification_2025_messaging_group.xml b/core/res/res/layout/notification_2025_messaging_group.xml index ecaf0b9a785f..ba0ce7b21b80 100644 --- a/core/res/res/layout/notification_2025_messaging_group.xml +++ b/core/res/res/layout/notification_2025_messaging_group.xml @@ -53,7 +53,6 @@ android:id="@+id/group_message_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_text_margin_top" android:spacing="2dp" /> </com.android.internal.widget.RemeasuringLinearLayout> <FrameLayout diff --git a/core/res/res/layout/notification_2025_reply_history_container.xml b/core/res/res/layout/notification_2025_reply_history_container.xml index 6923b59f34dc..256f7b89c784 100644 --- a/core/res/res/layout/notification_2025_reply_history_container.xml +++ b/core/res/res/layout/notification_2025_reply_history_container.xml @@ -28,16 +28,16 @@ android:layout_width="match_parent" android:layout_height="1dip" android:id="@+id/action_divider" - android:layout_marginTop="@dimen/notification_content_margin" - android:layout_marginBottom="@dimen/notification_content_margin" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginTop="@dimen/notification_2025_margin" + android:layout_marginBottom="@dimen/notification_2025_margin" + android:layout_marginEnd="@dimen/notification_2025_margin" android:background="@drawable/notification_template_divider" /> <TextView android:id="@+id/notification_material_reply_text_3" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:visibility="gone" android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply" android:singleLine="true" /> @@ -46,7 +46,7 @@ android:id="@+id/notification_material_reply_text_2" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:visibility="gone" android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply" android:singleLine="true" /> @@ -56,13 +56,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:layout_marginEnd="@dimen/notification_content_margin_end"> + android:layout_marginEnd="@dimen/notification_2025_margin"> <TextView android:id="@+id/notification_material_reply_text_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_gravity="center" android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply" android:singleLine="true" /> diff --git a/core/res/res/layout/notification_2025_template_collapsed_base.xml b/core/res/res/layout/notification_2025_template_collapsed_base.xml index 63f32e3b3cd2..57c89b91cff7 100644 --- a/core/res/res/layout/notification_2025_template_collapsed_base.xml +++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml @@ -74,7 +74,6 @@ android:id="@+id/notification_headerless_view_column" android:layout_width="0px" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" android:layout_weight="1" android:layout_marginVertical="@dimen/notification_2025_reduced_margin" android:orientation="vertical" @@ -157,7 +156,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" diff --git a/core/res/res/layout/notification_2025_template_collapsed_call.xml b/core/res/res/layout/notification_2025_template_collapsed_call.xml index 732021c65742..c57196e9c9e8 100644 --- a/core/res/res/layout/notification_2025_template_collapsed_call.xml +++ b/core/res/res/layout/notification_2025_template_collapsed_call.xml @@ -35,7 +35,6 @@ <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="@dimen/notification_2025_min_height" android:clipChildren="false" android:layout_weight="1" > @@ -78,9 +77,7 @@ android:id="@+id/notification_headerless_view_column" android:layout_width="0px" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" android:layout_weight="1" - android:layout_marginBottom="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_margin" android:clipChildren="false" android:orientation="vertical" @@ -152,7 +149,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" @@ -173,21 +170,13 @@ </FrameLayout> - <LinearLayout - android:id="@+id/notification_action_list_margin_target" + <include layout="@layout/notification_template_smart_reply_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="-20dp" - android:clipChildren="false" - android:orientation="vertical"> - <include layout="@layout/notification_template_smart_reply_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" - android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" /> - <include layout="@layout/notification_2025_action_list" /> - </LinearLayout> + android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" + android:layout_marginStart="@dimen/notification_2025_content_margin_start" + android:layout_marginEnd="@dimen/notification_2025_margin" /> + <include layout="@layout/notification_2025_action_list" /> </LinearLayout> </com.android.internal.widget.CallLayout> diff --git a/core/res/res/layout/notification_2025_template_collapsed_conversation.xml b/core/res/res/layout/notification_2025_template_collapsed_conversation.xml index 1ee7ddc8d060..1c6fcb50dca5 100644 --- a/core/res/res/layout/notification_2025_template_collapsed_conversation.xml +++ b/core/res/res/layout/notification_2025_template_collapsed_conversation.xml @@ -35,7 +35,6 @@ <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="@dimen/notification_2025_min_height" android:clipChildren="false" android:layout_weight="1" > @@ -78,17 +77,11 @@ android:clipChildren="false" > - <!-- - NOTE: because messaging will always have 2 lines, this LinearLayout should NOT - have the id/notification_headerless_view_column, as that is used for modifying - vertical margins to accommodate the single-line state that base supports - --> <LinearLayout + android:id="@+id/notification_headerless_view_column" android:layout_width="0px" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" android:layout_weight="1" - android:layout_marginBottom="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_margin" android:layout_marginStart="@dimen/notification_2025_content_margin_start" android:clipChildren="false" @@ -150,7 +143,6 @@ android:layout_height="@dimen/notification_right_icon_size" android:layout_gravity="center_vertical|end" android:layout_marginTop="@dimen/notification_2025_margin" - android:layout_marginBottom="@dimen/notification_2025_margin" android:layout_marginStart="@dimen/notification_2025_right_icon_content_margin" android:forceHasOverlappingRendering="false" android:spacing="0dp" @@ -175,7 +167,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" @@ -196,20 +188,13 @@ </FrameLayout> - <LinearLayout - android:id="@+id/notification_action_list_margin_target" + <include layout="@layout/notification_template_smart_reply_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="-20dp" - android:clipChildren="false" - android:orientation="vertical"> - <include layout="@layout/notification_template_smart_reply_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" - android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" /> + android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" + android:layout_marginStart="@dimen/notification_2025_content_margin_start" + android:layout_marginEnd="@dimen/notification_2025_margin" /> <include layout="@layout/notification_2025_action_list" /> + </LinearLayout> -</LinearLayout> </com.android.internal.widget.ConversationLayout> diff --git a/core/res/res/layout/notification_2025_template_collapsed_media.xml b/core/res/res/layout/notification_2025_template_collapsed_media.xml index 629af77b3dda..de82f9feb512 100644 --- a/core/res/res/layout/notification_2025_template_collapsed_media.xml +++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml @@ -76,7 +76,6 @@ android:id="@+id/notification_headerless_view_column" android:layout_width="0px" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" android:layout_weight="1" android:layout_marginVertical="@dimen/notification_2025_reduced_margin" android:orientation="vertical" @@ -178,7 +177,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" diff --git a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml index af660254d172..8e2cb23f1198 100644 --- a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml +++ b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml @@ -38,7 +38,6 @@ <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="@dimen/notification_2025_min_height" android:clipChildren="false" android:layout_weight="1" > @@ -61,7 +60,8 @@ android:layout_width="@dimen/notification_2025_icon_circle_size" android:layout_height="@dimen/notification_2025_icon_circle_size" android:layout_alignParentStart="true" - android:layout_margin="@dimen/notification_2025_margin" + android:layout_marginHorizontal="@dimen/notification_2025_margin" + android:layout_marginTop="@dimen/notification_2025_margin" android:background="@drawable/notification_icon_circle" android:padding="@dimen/notification_2025_icon_circle_padding" /> @@ -89,17 +89,11 @@ android:clipChildren="false" > - <!-- - NOTE: because messaging will always have 2 lines, this LinearLayout should NOT - have the id/notification_headerless_view_column, as that is used for modifying - vertical margins to accommodate the single-line state that base supports - --> <LinearLayout + android:id="@+id/notification_headerless_view_column" android:layout_width="0px" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" android:layout_weight="1" - android:layout_marginBottom="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_margin" android:layout_marginStart="@dimen/notification_2025_content_margin_start" android:clipChildren="false" @@ -161,7 +155,6 @@ android:layout_height="@dimen/notification_right_icon_size" android:layout_gravity="center_vertical|end" android:layout_marginTop="@dimen/notification_2025_margin" - android:layout_marginBottom="@dimen/notification_2025_margin" android:layout_marginStart="@dimen/notification_2025_right_icon_content_margin" android:forceHasOverlappingRendering="false" android:spacing="0dp" @@ -186,7 +179,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" @@ -207,20 +200,13 @@ </FrameLayout> - <LinearLayout - android:id="@+id/notification_action_list_margin_target" + <include layout="@layout/notification_template_smart_reply_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="-20dp" - android:clipChildren="false" - android:orientation="vertical"> - <include layout="@layout/notification_template_smart_reply_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" - android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" /> + android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" + android:layout_marginStart="@dimen/notification_2025_content_margin_start" + android:layout_marginEnd="@dimen/notification_2025_margin" /> <include layout="@layout/notification_2025_action_list" /> + </LinearLayout> -</LinearLayout> </com.android.internal.widget.MessagingLayout> diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml index 52bc7b8ea3bb..b32a7788c433 100644 --- a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml +++ b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml @@ -76,7 +76,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" android:layout_width="wrap_content" diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml index be6404609f25..268396f11cab 100644 --- a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml +++ b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml @@ -103,7 +103,7 @@ android:id="@+id/expand_button_touch_container" android:layout_width="wrap_content" android:layout_height="match_parent" - android:minWidth="@dimen/notification_content_margin_end" + android:minWidth="@dimen/notification_2025_margin" > <include layout="@layout/notification_2025_expand_button" android:layout_width="wrap_content" diff --git a/core/res/res/layout/notification_2025_template_expanded_base.xml b/core/res/res/layout/notification_2025_template_expanded_base.xml index 76a85813b980..58b26c905162 100644 --- a/core/res/res/layout/notification_2025_template_expanded_base.xml +++ b/core/res/res/layout/notification_2025_template_expanded_base.xml @@ -24,10 +24,8 @@ > <LinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/notification_content_margin" android:orientation="vertical" > @@ -47,11 +45,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" > - <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_2025_title" /> <include layout="@layout/notification_template_text_multiline" /> @@ -78,7 +76,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" /> diff --git a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml index 999afa66c65b..f6a17ef6d46f 100644 --- a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml +++ b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml @@ -28,7 +28,6 @@ <include layout="@layout/notification_2025_right_icon" /> <LinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top" @@ -43,11 +42,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" > - <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_2025_title" /> <include layout="@layout/notification_template_progress" @@ -67,7 +66,7 @@ android:layout_weight="1" android:layout_marginTop="13dp" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:background="@drawable/notification_big_picture_outline" android:clipToOutline="true" android:scaleType="centerCrop" @@ -85,7 +84,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" /> diff --git a/core/res/res/layout/notification_2025_template_expanded_big_text.xml b/core/res/res/layout/notification_2025_template_expanded_big_text.xml index c9206eddbcde..540444ea4da4 100644 --- a/core/res/res/layout/notification_2025_template_expanded_big_text.xml +++ b/core/res/res/layout/notification_2025_template_expanded_big_text.xml @@ -26,11 +26,9 @@ <include layout="@layout/notification_2025_template_header" /> <com.android.internal.widget.RemeasuringLinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" - android:layout_marginBottom="@dimen/notification_content_margin" android:clipToPadding="false" android:orientation="vertical" > @@ -43,13 +41,13 @@ android:layout_height="wrap_content" android:layout_gravity="top" android:paddingStart="@dimen/notification_2025_content_margin_start" - android:paddingEnd="@dimen/notification_content_margin_end" + android:paddingEnd="@dimen/notification_2025_margin" android:clipToPadding="false" android:orientation="vertical" android:layout_weight="1" > - <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_2025_title" /> <include layout="@layout/notification_template_progress" @@ -84,7 +82,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" /> diff --git a/core/res/res/layout/notification_2025_template_expanded_call.xml b/core/res/res/layout/notification_2025_template_expanded_call.xml index ec214554a30b..60b32002d484 100644 --- a/core/res/res/layout/notification_2025_template_expanded_call.xml +++ b/core/res/res/layout/notification_2025_template_expanded_call.xml @@ -30,7 +30,6 @@ <include layout="@layout/notification_2025_conversation_header"/> <com.android.internal.widget.RemeasuringLinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" @@ -46,12 +45,12 @@ android:layout_gravity="top" android:layout_weight="1" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" android:clipChildren="false" > - <include layout="@layout/notification_template_part_line1"/> + <include layout="@layout/notification_2025_title"/> <include layout="@layout/notification_template_text_multiline" /> @@ -62,7 +61,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" /> + android:layout_marginEnd="@dimen/notification_2025_margin" /> <include layout="@layout/notification_2025_action_list" /> diff --git a/core/res/res/layout/notification_2025_template_expanded_conversation.xml b/core/res/res/layout/notification_2025_template_expanded_conversation.xml index 6ee82fa116ff..e085d47d4579 100644 --- a/core/res/res/layout/notification_2025_template_expanded_conversation.xml +++ b/core/res/res/layout/notification_2025_template_expanded_conversation.xml @@ -29,7 +29,6 @@ <include layout="@layout/notification_2025_conversation_header"/> <com.android.internal.widget.RemeasuringLinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" @@ -44,19 +43,20 @@ android:layout_height="wrap_content" android:layout_gravity="top" android:layout_weight="1" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" android:clipChildren="false" > - <include layout="@layout/notification_template_part_line1"/> + <include layout="@layout/notification_2025_title"/> <com.android.internal.widget.MessagingLinearLayout android:id="@+id/notification_messaging" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="@dimen/notification_2025_margin" android:clipChildren="false" - android:spacing="@dimen/notification_messaging_spacing" /> + android:spacing="@dimen/notification_2025_messaging_spacing" /> </com.android.internal.widget.RemeasuringLinearLayout> <include layout="@layout/notification_template_smart_reply_container" @@ -64,7 +64,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" /> + android:layout_marginEnd="@dimen/notification_2025_margin" /> <include layout="@layout/notification_2025_action_list" /> diff --git a/core/res/res/layout/notification_2025_template_expanded_inbox.xml b/core/res/res/layout/notification_2025_template_expanded_inbox.xml index 1eaef228aaca..55253d0ce5f8 100644 --- a/core/res/res/layout/notification_2025_template_expanded_inbox.xml +++ b/core/res/res/layout/notification_2025_template_expanded_inbox.xml @@ -24,7 +24,6 @@ > <include layout="@layout/notification_2025_template_header" /> <LinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top" @@ -39,12 +38,12 @@ android:layout_height="wrap_content" android:layout_gravity="top" android:paddingStart="@dimen/notification_2025_content_margin_start" - android:paddingEnd="@dimen/notification_content_margin_end" + android:paddingEnd="@dimen/notification_2025_margin" android:layout_weight="1" android:clipToPadding="false" android:orientation="vertical" > - <include layout="@layout/notification_template_part_line1" + <include layout="@layout/notification_2025_title" android:layout_width="match_parent" android:layout_height="wrap_content" /> <include layout="@layout/notification_template_progress" @@ -126,7 +125,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" /> <include layout="@layout/notification_2025_action_list" /> </LinearLayout> diff --git a/core/res/res/layout/notification_2025_template_expanded_media.xml b/core/res/res/layout/notification_2025_template_expanded_media.xml index 801e339b3a92..5e97607dc65b 100644 --- a/core/res/res/layout/notification_2025_template_expanded_media.xml +++ b/core/res/res/layout/notification_2025_template_expanded_media.xml @@ -41,10 +41,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" > - <include layout="@layout/notification_template_part_line1"/> + <include layout="@layout/notification_2025_title"/> <include layout="@layout/notification_template_text"/> </LinearLayout> @@ -53,7 +53,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_media_actions_margin_start" - android:minHeight="@dimen/notification_content_margin" + android:minHeight="@dimen/notification_2025_margin" > <!-- Nesting in FrameLayout is required to ensure that the marginStart actually applies diff --git a/core/res/res/layout/notification_2025_template_expanded_messaging.xml b/core/res/res/layout/notification_2025_template_expanded_messaging.xml index 62059af7f056..14ed536a9a5c 100644 --- a/core/res/res/layout/notification_2025_template_expanded_messaging.xml +++ b/core/res/res/layout/notification_2025_template_expanded_messaging.xml @@ -29,7 +29,6 @@ <include layout="@layout/notification_2025_template_header"/> <com.android.internal.widget.RemeasuringLinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" @@ -44,19 +43,20 @@ android:layout_height="wrap_content" android:layout_gravity="top" android:layout_weight="1" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" android:clipChildren="false" > - <include layout="@layout/notification_template_part_line1"/> + <include layout="@layout/notification_2025_title"/> <com.android.internal.widget.MessagingLinearLayout android:id="@+id/notification_messaging" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="@dimen/notification_2025_margin" android:clipChildren="false" - android:spacing="@dimen/notification_messaging_spacing" /> + android:spacing="@dimen/notification_2025_messaging_spacing" /> </com.android.internal.widget.RemeasuringLinearLayout> <include layout="@layout/notification_template_smart_reply_container" @@ -64,7 +64,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" /> + android:layout_marginEnd="@dimen/notification_2025_margin" /> <include layout="@layout/notification_2025_action_list" /> diff --git a/core/res/res/layout/notification_2025_template_expanded_progress.xml b/core/res/res/layout/notification_2025_template_expanded_progress.xml index cf39d8b08c4f..1315481d86c5 100644 --- a/core/res/res/layout/notification_2025_template_expanded_progress.xml +++ b/core/res/res/layout/notification_2025_template_expanded_progress.xml @@ -25,10 +25,8 @@ > <LinearLayout - android:id="@+id/notification_action_list_margin_target" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/notification_content_margin" android:orientation="vertical" > @@ -48,11 +46,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:orientation="vertical" > - <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_2025_title" /> <include layout="@layout/notification_template_text_multiline" /> @@ -114,7 +112,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" /> diff --git a/core/res/res/layout/notification_2025_template_heads_up_base.xml b/core/res/res/layout/notification_2025_template_heads_up_base.xml index 4d3b2453637d..e416c5054e00 100644 --- a/core/res/res/layout/notification_2025_template_heads_up_base.xml +++ b/core/res/res/layout/notification_2025_template_heads_up_base.xml @@ -56,7 +56,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_2025_content_margin_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginEnd="@dimen/notification_2025_margin" android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" /> diff --git a/core/res/res/layout/notification_2025_title.xml b/core/res/res/layout/notification_2025_title.xml new file mode 100644 index 000000000000..7cea5ea08449 --- /dev/null +++ b/core/res/res/layout/notification_2025_title.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2025 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 + --> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/title" + android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:maxLines="2" + android:ellipsize="end" + android:textAlignment="viewStart" + /> diff --git a/core/res/res/layout/notification_close_button.xml b/core/res/res/layout/notification_close_button.xml index 5eff84e6981a..9656d3945d92 100644 --- a/core/res/res/layout/notification_close_button.xml +++ b/core/res/res/layout/notification_close_button.xml @@ -17,13 +17,14 @@ <com.android.internal.widget.NotificationCloseButton xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/close_button" + android:background="@drawable/close_button_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|end" android:contentDescription="@string/close_button_text" android:visibility="gone" android:src="@drawable/notification_close_button_icon" - android:padding="2dp" + android:padding="@dimen/notification_close_button_padding" android:scaleType="fitCenter" android:importantForAccessibility="no" > diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 59ac5c68f9a5..568468b51f47 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vra ontsluitpatroon voordat jy ontspeld"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vra wagwoord voordat jy ontspeld"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Deur jou admin geïnstalleer.\nGaan na instellings om toegestaande toestemmings te sien"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Deur jou admin opgedateer.\nGaan na instellings om toegestaande toestemmings te sien"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Uitgevee deur jou administrateur"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte, sekere kenmerke en sommige netwerkverbindings af"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 169e0208cf34..20d5336959d2 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ሥርዓተ-ጥለት ጠይቅ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"በአስተዳዳሪዎ ተጭኗል።\nየተፈቀዱ ፍቃዶችን ለማየት ወደ ቅንብሮች ይሂዱ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"በአስተዳዳሪዎ ተዘምኗል።\nየተፈቀዱ ፍቃዶችን ለማየት ወደ ቅንብሮች ይሂዱ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"እሺ"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ባትሪ ቆጣቢ ጠቆር ያለ ገጽታን ያበራል እና የጀርባ እንቅስቃሴን፣ አንዳንድ ዕይታዊ ውጤቶችን፣ አንዳንድ ባህሪዎችን፣ እና አንዳንድ የአውታረ መረብ ግንኙነቶችን ይገድባል ወይም ያጠፋል።"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 1d2bd776b505..ffc144416d91 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1969,8 +1969,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال نقش فتح القفل قبل إزالة التثبيت"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"تم التثبيت من قِبل المشرف.\nانتقِل إلى الإعدادات للاطّلاع على الأذونات الممنوحة"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"تم التحديث من قِبل المشرف.\nيُرجى الانتقال إلى الإعدادات للاطّلاع على الأذونات الممنوحة"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"حسنًا"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"يؤدي استخدام ميزة \"توفير شحن البطارية\" إلى تفعيل وضع \"المظهر الداكن\" وتقييد أو إيقاف الأنشطة في الخلفية وبعض التأثيرات المرئية وميزات معيّنة وبعض اتصالات الشبكات."</string> @@ -2278,18 +2277,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"الانتقال للأسفل أو للأعلى"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"إيقاف مؤقت"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"تعديل الموضع"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"الانتقال للأعلى"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"الانتقال للأسفل"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"الانتقال لليمين"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"الانتقال لليسار"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"الخروج من وضع الانتقال"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"لوحة الانتقال"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"تم وضع <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> في الحزمة \"محظورة\"."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"هذا المستخدم أرسل صورة"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 606161c29f12..5c78cded7df6 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন কৰাৰ পূৰ্বে আনলক আৰ্হি দিবলৈ কওক"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন কৰাৰ পূৰ্বে পাছৱৰ্ড দিবলৈ কওক"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"আপোনাৰ প্ৰশাসকে ইনষ্টল কৰিছে।\nপ্ৰদান কৰা অনুমতিসমূহ চাবলৈ ছেটিঙলৈ যাওক"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"আপোনাৰ প্ৰশাসকে আপডে’ট কৰিছে।\nপ্ৰদান কৰা অনুমতিসমূহ চাবলৈ ছেটিঙলৈ যাওক"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপোনাৰ প্ৰশাসকে মচিছে"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট, নিৰ্দিষ্ট কিছুমান সুবিধা আৰু নেটৱৰ্কৰ সংযোগ সীমিত অথবা অফ কৰে।"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 904194f122b8..c8b500be22c6 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Qrafik açar istənilsin"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ayırmadan öncə parol istənilsin"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Admin quraşdırıb.\nVerilən icazələrə baxmaq üçün ayarlara keçin"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Admin güncəlləyib.\nTəmin edilən icazələrə baxmaq üçün ayarlara keçin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Admin tərəfindən silindi"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Enerjiyə Qənaət rejimi Tünd temanı aktivləşdirir, habelə arxa fon fəaliyyətini, bəzi vizual effektləri, müəyyən xüsusiyyətləri və bəzi şəbəkə bağlantılarını məhdudlaşdırır, yaxud söndürür."</string> @@ -2274,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Sürüşdürün"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Durdurun"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Mövqe"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Yuxarı sürüşdürün"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Aşağı sürüşdürün"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Sola sürüşdürün"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Sağa sürüşdürün"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sürüşdürmə rejimindən çıxın"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Sürüşdürmə paneli"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> MƏHDUDLAŞDIRILMIŞ səbətinə yerləşdirilib"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"şəkil göndərdi"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index e7fff52222f1..d1889b84e90f 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Ažurirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 94739b353de9..68fe703644a9 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1967,8 +1967,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запытваць узор разблакіроўкі перад адмацаваннем"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запытваць пароль перад адмацаваннем"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Усталявана адміністратарам.\nКаб паглядзець дадзеныя дазволы, перайдзіце ў налады"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Абноўлена адміністратарам.\nКаб праглядзець дадзеныя дазволы, перайдзіце ў налады"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Выдалены вашым адміністратарам"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"У рэжыме энергазберажэння ўключаецца цёмная тэма і выключаюцца ці абмяжоўваюцца дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты, пэўныя функцыі і падключэнні да сетак."</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 2bd7d1d8ac60..67e711f115df 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Превъртане"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Пауза"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиция"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Превъртане нагоре"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Превъртане надолу"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Превъртане наляво"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Превъртане надясно"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Изход от режима за превъртане"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панел за превъртане"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакетът <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е поставен в ОГРАНИЧЕНИЯ контейнер"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"изпратено изображение"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 16a7e9aad04a..12bf5dab6561 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন করার আগে পাসওয়ার্ড চান"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"আপনার অ্যাডমিন ইনস্টল করেছেন।\nঅনুমোদন করা অনুমতি দেখতে সেটিংসে যান"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"আপনার অ্যাডমিন আপডেট করেছেন।\nঅনুমোদন করা অনুমতি দেখতে সেটিংসে যান"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপনার প্রশাসক মুছে দিয়েছেন"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ব্যাটারি সেভার ডার্ক থিম চালু করে এবং ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট, নির্দিষ্ট ফিচার ও কয়েকটি নেটওয়ার্ক কানেকশনের ব্যবহার সীমিত করে বা বন্ধ করে দেয়।"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index e5a78a34d5d6..441d51461f08 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje prije poništavanja kačenja"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku prije nego se otkači"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je vaš administrator.\nIdite u postavke da pregledate data odobrenja"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Ažurirao je vaš administrator.\nIdite u postavke da pregledate data odobrenja"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je vaš administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index b70bb3337b7c..efde1506e7be 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instal·lat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Actualitzat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions de xarxa."</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index c4e69ab37ef7..59de93743290 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1967,8 +1967,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Nainstalováno administrátorem.\nUdělená oprávnění si můžete prohlédnout v nastavení."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Aktualizováno administrátorem.\nUdělená oprávnění si můžete prohlédnout v nastavení."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Spořič baterie zapíná tmavý motiv a omezuje či vypíná aktivitu na pozadí, některé vizuální efekty, některé funkce a připojení k některým sítím."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index c0447239859d..1038ff0bcf8f 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Bed om oplåsningsmønster ved deaktivering"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bed om adgangskode inden frigørelse"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Installeret af din administrator.\nGå til Indstillinger for at se de tilladelser, der er blevet givet"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Opdateret af din administrator.\nGå til Indstillinger for at se de tilladelser, der er blevet givet"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet af din administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterisparefunktionen aktiverer Mørkt tema og begrænser eller deaktiverer aktivitet i baggrunden og visse visuelle effekter, funktioner og netværksforbindelser."</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0d371cceba6b..c13dacad4dea 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vor dem Beenden nach Entsperrungsmuster fragen"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vor dem Beenden nach Passwort fragen"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Von deinem Administrator installiert.\nRufe die Einstellungen auf, um gewährte Berechtigungen anzusehen."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Von deinem Administrator aktualisiert.\nRufe die Einstellungen auf, um gewährte Berechtigungen anzusehen."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Von deinem Administrator gelöscht"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Der Energiesparmodus aktiviert das dunkle Design. Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen werden eingeschränkt oder deaktiviert."</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 55d28c500b2d..50b06dfbc8b6 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Εγκαταστάθηκε από τον διαχειριστή σας.\nΜεταβείτε στις ρυθμίσεις για να δείτε τις άδειες που έχουν εκχωρηθεί"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Ενημερώθηκε από τον διαχειριστή σας.\nΜεταβείτε στις ρυθμίσεις για να δείτε τις άδειες που έχουν εκχωρηθεί"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Διαγράφηκε από τον διαχειριστή σας"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Η Εξοικονόμηση μπαταρίας ενεργοποιεί το Σκούρο θέμα και περιορίζει ή απενεργοποιεί τη δραστηριότητα στο παρασκήνιο, ορισμένα οπτικά εφέ, συγκεκριμένες λειτουργίες και κάποιες συνδέσεις δικτύου."</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index b94840430e60..74462e996b5b 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing-aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing-aid microphone for hands-free calling. This only switches your mic during the call."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 30843adab245..eb6f28140b11 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -2486,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index bcfc861932fb..9fa268338d4a 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing-aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing-aid microphone for hands-free calling. This only switches your mic during the call."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 15ea9bf0007c..e162a6094719 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing-aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing-aid microphone for hands-free calling. This only switches your mic during the call."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 1e10140e2bf1..38708696debc 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -2274,18 +2274,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplazamiento"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desplazarse hacia arriba"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desplazarse hacia abajo"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desplazarse hacia la izquierda"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desplazarse hacia la derecha"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Salir del modo de desplazamiento"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel de desplazamiento"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el bucket RESTRICTED"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"envió una imagen"</string> @@ -2493,8 +2487,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"Trabajo 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"Probar"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisando"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabajo"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espacio privado"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clon"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 189a027350bb..330039740ea1 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir patrón de desbloqueo para dejar de fijar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para desactivar"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado por tu administrador.\nVe a Ajustes para ver los permisos concedidos."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Actualizado por tu administrador.\nVe a Ajustes para ver los permisos concedidos."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 893bc4e755fa..c172de8671c9 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Kas vahetada telefoni mikrofonile?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Kas vahetada kuuldeaparaadi mikrofonile?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Parema heli tagamiseks või siis, kui tele kuuldeaparaadi aku on tühi. See vahetab teie mikrofoni ainult kõne ajal."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Saate kasutada oma kuuldeaparaadi mikrofon vabakäerežiimis helistamiseks. See vahetab teie mikrofoni ainult kõne ajal."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Parema heli tagamiseks või siis, kui teie kuuldeaparaadi aku on tühi. See vahetab teie mikrofoni ainult kõne ajal."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Saate kasutada oma kuuldeaparaadi mikrofoni vabakäerežiimis helistamiseks. See vahetab teie mikrofoni ainult kõne ajal."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Vaheta"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Seaded"</string> <string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Installis teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Värskendas teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akusäästja lülitab sisse tumeda teema ja lülitab välja taustategevused, mõned visuaalsed efektid, teatud funktsioonid ja võrguühendused või piirab neid."</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index fb60c8dc6e8d..24dbe4bb580c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Eskatu pasahitza aingura kendu aurretik"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Administratzaileak instalatu du.\nEmandako baimenak ikusteko, joan ezarpenetara."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Administratzaileak eguneratu du.\nEmandako baimenak ikusteko, joan ezarpenetara."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratzaileak ezabatu du"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Bateria-aurreztaileak gai iluna aktibatzen du, eta atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk mugatzen edo desaktibatzen ditu."</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 24db15aa7b26..f31bb1044c96 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"پیمایش"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"توقف موقت"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"موقعیت"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"پیمایش به بالا"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"پیمایش به پایین"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"پیمایش به چپ"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"پیمایش به راست"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"خارج شدن از حالت پیمایش"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"پانل پیمایش"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> در سطل «محدودشده» قرار گرفت"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"تصویری ارسال کرد"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index cb16427bd351..f1a5fbcdbcc4 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Järjestelmänvalvojan asentama.\nTarkista myönnetyt luvat asetuksista."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Järjestelmänvalvojan päivittämä.\nTarkista myönnetyt luvat asetuksista"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, tiettyjä ominaisuuksia sekä joitakin visuaalisia tehosteita ja verkkoyhteyksiä."</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index c2b368e7c02c..a7b12891d7b1 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1820,9 +1820,9 @@ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec trois doigts et relâchez rapidement."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passer au micro du téléphone?"</string> - <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro pour la prothèse auditive?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro de la prothèse auditive?"</string> <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour profiter d\'un meilleur son ou si la pile de votre prothèse auditive est faible. Cette option ne change votre micro que pendant l\'appel."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser votre microphone pour prothèse auditive pour faire des appels en mode mains libres. Cette option ne change votre micro que pendant l\'appel."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le microphone de votre prothèse auditive pour faire des appels en mode mains libres. Cette option ne change votre micro que pendant l\'appel."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string> <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string> @@ -2274,18 +2274,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Faire défiler"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Faire défiler vers le haut"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Faire défiler vers le bas"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Faire défiler vers la gauche"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Faire défiler vers la droite"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sortir du mode de défilement"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panneau de défilement"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le compartiment RESTREINT"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"a envoyé une image"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 1cf540905515..213c25696ec0 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1821,8 +1821,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passer au micro du téléphone ?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro de l\'appareil auditif ?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour améliorer le son ou si la batterie de votre appareil auditif est faible. Cette option change uniquement le micro pendant l\'appel."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le micro de votre appareil auditif pour passer des appels en mode mains-libres. Cette option change uniquement le micro pendant l\'appel."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour un meilleur son ou si la batterie de votre appareil auditif est faible. Cette option ne change le micro que pendant l\'appel."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le micro de votre appareil auditif pour passer des appels en mode mains-libres. Cette option ne change le micro que pendant l\'appel."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string> <string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string> @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Installé par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Mis à jour par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"L\'économiseur de batterie active le thème sombre et limite ou désactive l\'activité en arrière-plan ainsi que certains effets visuels, fonctionnalités et connexions réseau."</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index ecd2d4b197d2..8c265b02b93e 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrón de desbloqueo antes de soltar a fixación"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir contrasinal antes de soltar a fixación"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pola persoa administradora.\nVai á configuración para ver os permisos concedidos"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Actualizado pola persoa administradora.\nVai á configuración para ver os permisos concedidos"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado polo teu administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Coa función Aforro de batería, actívase o tema escuro e restrínxense ou desactívanse a actividade en segundo plano, algúns efectos visuais e determinadas funcións e conexións de rede."</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index b4095ef8dbd3..c4da34989482 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"તમારા ઍડમિન દ્વારા ઇન્સ્ટૉલ કરવામાં આવ્યું છે.\nઆપેલી પરવાનગીઓ જોવા માટે સેટિંગ પર જાઓ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"તમારા ઍડમિન દ્વારા અપડેટ કરવામાં આવ્યું છે.\nઆપેલી પરવાનગીઓ જોવા માટે સેટિંગ પર જાઓ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખવામાં આવેલ છે"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ઓકે"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"બૅટરી સેવર ઘેરી થીમની સુવિધા ચાલુ કરે છે અને બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ, અમુક સુવિધાઓ અને કેટલાક નેટવર્ક કનેક્શન મર્યાદિત કે બંધ કરે છે."</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index f93b8a2ec269..01e5c7786cb7 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"क्या आपको फ़ोन के माइक्रोफ़ोन पर स्विच करना है?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"क्या आपको कान की मशीन के माइक पर स्विच करना है?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"बेहतर आवाज़ के लिए या कान की मशीन की बैटरी कम होने पर. यह सिर्फ़ कॉल के दौरान आपका माइक चालू करता है."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"बोलकर कॉल का जवाब देने के लिए, \'कान की मशीन का माइक्रोफ़ोन\' इस्तेमाल किया जा सकता है. इससे, कॉल के दौरान सिर्फ़ आपका माइक चालू या बंद होता है."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"बेहतर आवाज़ के लिए या कान की मशीन की बैटरी कम होने पर, इसका इस्तेमाल करें. इससे सिर्फ़ कॉल के दौरान आपका माइक चालू होता है."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"बोलकर कॉल का जवाब देने के लिए, \'कान की मशीन का माइक्रोफ़ोन\' इस्तेमाल किया जा सकता है. इससे सिर्फ़ कॉल के दौरान आपका माइक चालू होता है."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"स्विच करें"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिंग"</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"इसे आपके एडमिन ने इंस्टॉल किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"इसे आपके एडमिन ने अपडेट किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"आपके व्यवस्थापक ने हटा दिया है"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ठीक है"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"बैटरी सेवर, गहरे रंग वाली थीम को चालू करता है. साथ ही, इस मोड में बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और कुछ खास सुविधाएं कम या बंद हो जाती हैं. कुछ इंटरनेट कनेक्शन भी पूरी तरह काम नहीं करते."</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 336e37956783..826b860dfc2b 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1821,8 +1821,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povećavanje"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite li se prebaciti na mikrofon telefona?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite li se prebaciti na mikrofon slušnog pomagala?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za bolji zvuk ili ako je razina baterije slušnog pomagala niska. Time se mikrofon prebacuje samo tijekom poziva."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnog pomagala možete koristiti za pozivanje bez upotrebe ruku. Time se mikrofon prebacuje samo tijekom poziva."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Da biste se bolje čuli ili ako je razina baterije slušnog pomagala niska. Mikrofon se koristi samo tijekom poziva."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnog pomagala možete koristiti za pozivanje bez upotrebe ruku. Mikrofon se koristi samo tijekom poziva."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prebaci"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Postavke"</string> <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje radi otkvačivanja"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži zaporku radi otkvačivanja"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao vaš administrator.\nOtvorite postavke da biste pregledali dodijeljena dopuštenja"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Ažurirao je vaš administrator.\nOtvorite postavke da biste pregledali dodijeljena dopuštenja"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"U redu"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index af9ee628e4b1..2fd68c11ba7b 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Ոլորել"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Դադարեցնել"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Դիրքը"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Թերթել վերև"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Թերթել ներքև"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Թերթել ձախ"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Թերթել աջ"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Դուրս գալ թերթելու ռեժիմից"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Թերթելու վահանակ"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> փաթեթը գցվեց ՍԱՀՄԱՆԱՓԱԿՎԱԾ զամբյուղի մեջ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>՝"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"օգտատերը պատկեր է ուղարկել"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 90b1ddfcc2cb..6e686b4263dd 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Meminta pola pembukaan kunci sebelum melepas sematan"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Meminta sandi sebelum melepas sematan"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Diinstal oleh admin Anda.\nBuka setelan untuk melihat izin yang diberikan"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Diperbarui oleh admin Anda.\nBuka setelan untuk melihat izin yang diberikan"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dihapus oleh admin Anda"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Oke"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Penghemat Baterai akan mengaktifkan Tema gelap dan membatasi atau menonaktifkan aktivitas latar belakang, beberapa efek visual, fitur tertentu, dan beberapa koneksi jaringan."</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 772be761426d..35b102e42933 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Stækkun"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Skipta yfir í hljóðnema símans?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Skipta yfir í hljóðnema heyrnartækis?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Fyrir betri hljómgæði eða ef lítil hleðsla er á heyrnartækinu. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Þú getur notað hljóðnema heyrnartækisins þíns til að hringja eða svara símtölum handfrjálst. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Til að auka hljómgæði eða ef hleðsla heyrnartækisins er lág. Aðeins verður skipt um hljóðnema meðan á símtali stendur."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Þú getur notað hljóðnema heyrnartækisins þíns til að hringja eða svara símtölum handfrjálst. Aðeins verður skipt um hljóðnema meðan á símtali stendur."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skipta"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Stillingar"</string> <string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2492,8 +2492,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"Vinna 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"Prófun"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Sameiginlegt"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"Eftirlit virkt"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Vinnusnið"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Leynirými"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Afrit"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index dd10d1d3688d..28aee0fbba0c 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1821,8 +1821,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ingrandimento"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passare al microfono dello smartphone?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passare al microfono dell\'apparecchio acustico?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Per una migliore resa audio o se la batteria dell\'apparecchio acustico è scarica. In questo modo, il microfono viene attivato solo durante la chiamata."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puoi usare il microfono dell\'apparecchio acustico per le chiamate in vivavoce. In questo modo, il microfono viene attivato solo durante la chiamata."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Per una migliore resa audio o se la batteria dell\'apparecchio acustico è scarica. Il cambio del microfono avviene solo durante la chiamata."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puoi usare il microfono dell\'apparecchio acustico per le chiamate in vivavoce. Il cambio del microfono avviene solo durante la chiamata."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambia"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Impostazioni"</string> <string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2493,8 +2493,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"Lavoro 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"Test"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Condiviso"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisione"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profilo di lavoro"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Spazio privato"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 1055612ff636..5eadbd413f2c 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"החבילה הותקנה על ידי האדמין.\nצריך לעבור להגדרות כדי לראות את ההרשאות שניתנו"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"החבילה עודכנה על ידי האדמין.\nצריך לעבור להגדרות כדי לראות את ההרשאות שניתנו"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"נמחקה על ידי מנהל המערכת"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"אישור"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים, תכונות מסוימות וחלק מהחיבורים לרשתות."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index ea101ec8ee84..207e030bc456 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"スクロール"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"一時停止"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"上にスクロール"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"下にスクロール"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"左にスクロール"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"右にスクロール"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"スクロール モードを終了"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"スクロール パネル"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> は RESTRICTED バケットに移動しました。"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"画像を送信しました"</string> @@ -2492,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"仕事用 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"テスト"</string> <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"管理者"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"仕事用プロファイル"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"プライベート スペース"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"複製"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 055c41201ced..a1a4f7282eae 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"გადაადგილება"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"პაუზა"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"პოზიცია"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ზემოთ გადაადგილება"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ქვემოთ გადაადგილება"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"მარცხნივ გადაადგილება"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"მარჯვნივ გადაადგილება"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"გადაადგილების რეჟიმიდან გასვლა"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"გადაადგილების არე"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> მოთავსდა კალათაში „შეზღუდული“"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"გაიგზავნა სურათი"</string> @@ -2492,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"სამსახური 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"სატესტო"</string> <string name="profile_label_communal" msgid="8743921499944800427">"საერთო"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"ზედამხედველობა"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"სამსახურის პროფილი"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"კერძო სივრცე"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"კლონის შექმნა"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 176645fb1a9a..24e45df6d1ac 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Телефонның микрофонына ауысу керек пе?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Есту аппаратының микрофонына ауысу керек пе?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дауыс жақсы шығу үшін немесе есту аппаратының батарея заряды аз болған жағдайда пайдалануға болады. Микрофонға тек қоңырау кезінде ауысады."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Дауыспен басқару арқылы қоңырау шалу үшін есту аппаратының микрофонын пайдалана аласыз. Микрофонға тек қоңырау кезінде ауысады."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дыбыс дұрыс естілмей тұрғанда немесе есту аппаратының батарея заряды аз болған жағдайда пайдалануға болады. Басқа микрофонға тек қоңырау кезінде ауысады."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Дауыспен басқару арқылы қоңырау шалу үшін есту аппаратының микрофонын пайдалана аласыз. Басқа микрофонға тек қоңырау кезінде ауысады."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Ауысу"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Босату алдында бекітпесін ашу өрнегін сұрау"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Босату алдында құпия сөзді сұрау"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Әкімшіңіз орнатты.\nБерілген рұқсаттарды көру үшін параметрлерге өтіңіз."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Әкімшіңіз жаңартты.\nБерілген рұқсаттарды көру үшін параметрлерге өтіңіз."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Әкімші жойған"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Жарайды"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батареяны үнемдеу режимі қараңғы режимді іске қосады және фондық әрекеттерге, кейбір визуалдық әсерлерге, белгілі бір функциялар мен кейбір желі байланыстарына шектеу қояды немесе оларды өшіреді."</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 63b05e670513..e9ee62aef689 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"សួររកលំនាំដោះសោមុនពេលដោះខ្ទាស់"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"សួររកពាក្យសម្ងាត់មុនពេលផ្ដាច់"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"បានដំឡើងដោយអ្នកគ្រប់គ្រងរបស់អ្នក។\nចូលទៅកាន់ការកំណត់ ដើម្បីមើលការអនុញ្ញាតដែលផ្ដល់ឱ្យ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"បានធ្វើបច្ចុប្បន្នភាពដោយអ្នកគ្រប់គ្រងរបស់អ្នក។\nចូលទៅកាន់ការកំណត់ ដើម្បីមើលការអនុញ្ញាតដែលផ្ដល់ឱ្យ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"លុបដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"មុខងារសន្សំថ្មបើកទម្រង់រចនាងងឹត និងដាក់កំហិត ឬបិទសកម្មភាពផ្ទៃខាងក្រោយ បែបផែនរូបភាពមួយចំនួន មុខងារជាក់លាក់ និងការតភ្ជាប់បណ្ដាញមួយចំនួន។"</string> @@ -2274,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"រំកិល"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ផ្អាក"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ទីតាំង"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"រំកិលឡើងលើ"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"រំកិលចុះក្រោម"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"រំកិលទៅឆ្វេង"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"រំកិលទៅស្ដាំ"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ចាកចេញពីមុខងាររំកិល"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ផ្ទាំងរំកិល"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ត្រូវបានដាក់ទៅក្នុងធុងដែលបានដាក់កំហិត"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>៖"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"បានផ្ញើរូបភាព"</string> @@ -2493,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"ការងារទី 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"ការធ្វើតេស្ត"</string> <string name="profile_label_communal" msgid="8743921499944800427">"ទូទៅ"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"កំពុងគ្រប់គ្រង"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"កម្រងព័ត៌មានការងារ"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"លំហឯកជន"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ក្លូន"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index f56f2c8571cb..c9a0f211a4e8 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ವಿರಾಮಗೊಳಿಸಿ"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ಸ್ಥಾನ"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ಮೇಲಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ಕೆಳಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ಎಡಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ಬಲಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ಸ್ಕ್ರಾಲ್ ಮೋಡ್ನಿಂದ ನಿರ್ಗಮಿಸಿ"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ಪ್ಯಾನೆಲ್ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ಬಂಧಿತ ಬಕೆಟ್ಗೆ ಹಾಕಲಾಗಿದೆ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 253d162427fa..852051f0d8e2 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"고정 해제 시 잠금 해제 패턴 요청"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"고정 해제 이전에 비밀번호 요청"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"관리자에 의해 설치되었습니다.\n부여된 권한을 확인하려면 설정으로 이동하세요."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"관리자에 의해 업데이트되었습니다.\n부여된 권한을 확인하려면 설정으로 이동하세요."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"관리자에 의해 삭제되었습니다."</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"확인"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"절전 모드는 어두운 테마를 사용하고 백그라운드 활동, 일부 시각 효과, 특정 기능 및 일부 네트워크 연결을 제한하거나 사용 중지합니다."</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 96f01ffcb93a..8115a000a42a 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Чоңойтуу"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Телефондун микрофонуна которуласызбы?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Угуу аппаратынын микрофонуна которуласызбы?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Үндүн сапатын жакшыртуу үчүн же угуу аппаратыңыздын батареясы аз болсо, телефондун микрофонун колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Угуу аппаратыңыздын микрофонун үн режиминде чалуу үчүн колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Угуу аппаратыңыз жакшы угулбай жатса же батареясы отурайын деп калса, микрофонго которула аласыз. Микрофонго чалуу учурунда гана которуласыз."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Телефон менен сүйлөшүп жатканда угуу аппаратыңыздын микрофонун колдоно аласыз. Микрофонго чалуу учурунда гана которуласыз."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Которулуу"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 4905a53b06f6..b9868d1f82f6 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ຖາມຫາຮູບແບບປົດລັອກກ່ອນຍົກເລີກການປັກໝຸດ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ຖາມຫາລະຫັດຜ່ານກ່ອນຍົກເລີກການປັກໝຸດ"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"ຕິດຕັ້ງໂດຍຜູ້ເບິ່ງແຍງຂອງທ່ານ.\nເຂົ້າໄປການຕັ້ງຄ່າເພື່ອເບິ່ງສິດທີ່ໄດ້ຮັບອະນຸຍາດ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"ອັບເດດໂດຍຜູ້ເບິ່ງແຍງຂອງທ່ານ.\nເຂົ້າໄປການຕັ້ງຄ່າເພື່ອເບິ່ງສິດທີ່ໄດ້ຮັບອະນຸຍາດ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ຖືກລຶບອອກໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ຕົກລົງ"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດໃຊ້ຮູບແບບສີສັນມືດ ແລະ ຈຳກັດ ຫຼື ປິດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກທາງພາບຈຳນວນໜຶ່ງ, ຄຸນສົມບັດບາງຢ່າງ ແລະ ການເຊື່ອມຕໍ່ເຄືອຂ່າຍບາງອັນ."</string> @@ -2274,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ເລື່ອນ"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ຢຸດຊົ່ວຄາວ"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ຕຳແໜ່ງ"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ເລື່ອນຂຶ້ນ"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ເລື່ອນລົງ"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ເລື່ອນໄປທາງຊ້າຍ"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ເລື່ອນໄປທາງຂວາ"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ອອກຈາກໂໝດເລື່ອນ"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ເລື່ອນແຜງ"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ຖືກວາງໄວ້ໃນກະຕ່າ \"ຈຳກັດ\" ແລ້ວ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ສົ່ງຮູບແລ້ວ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 07a6c6e663d2..c71c2b8e612e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -2275,18 +2275,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Slinkti"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pristabdyti"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicija"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Slinkti aukštyn"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Slinkti žemyn"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Slinkti į kairę"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Slinkti į dešinę"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Išeiti iš slinkimo režimo"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Slinkimo skydelis"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"„<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>“ įkeltas į grupę APRIBOTA"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"išsiuntė vaizdą"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 60a99b3fd338..252343724908 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pirms atspraušanas pieprasīt atbloķēšanas kombināciju"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pirms atspraušanas pieprasīt paroli"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalēja jūsu administrators.\nPārejiet uz iestatījumiem, lai skatītu piešķirtās atļaujas."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Instalēja jūsu administrators.\nPārejiet uz iestatījumiem, lai skatītu piešķirtās atļaujas."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dzēsa administrators"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Labi"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akumulatora enerģijas taupīšanas režīmā tiek ieslēgts tumšais motīvs un tiek ierobežotas vai izslēgtas darbības fonā, daži vizuālie efekti, noteiktas funkcijas un noteikti tīkla savienojumi."</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 6d98869e7b60..c6cb1faa850b 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирано од администраторот.\nОдете во „Поставки“ за да ги прегледате доделените дозволи"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Ажурирано од администраторот.\nОдете во „Поставки“ за да ги прегледате доделените дозволи"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Во ред"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"„Штедачот на батерија“ вклучува „Темна тема“ и ограничува или исклучува активност во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 58f4cf7b83cb..740c78386c3a 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1820,7 +1820,7 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Томруулах"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Утасны микрофон руу сэлгэх үү?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Сонсголын төхөөрөмжийн микрофон руу сэлгэх үү?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дуу чимээг сайжруулахын тулд эсвэл таны сонсголын төхөөрөмжийн батарей бага бол. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дуу чимээг сайжруулахын тулд эсвэл таны сонсголын төхөөрөмжийн цэнэг бага үед, зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string> <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Та гараас хамаарахгүй дуудлагад сонсголын төхөөрөмжийнхөө микрофоныг ашиглаж болно. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Сэлгэх"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Тохиргоо"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бэхэлснийг болиулахаас өмнө түгжээ тайлах хээ асуух"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Танай админ суулгасан.\nОлгосон зөвшөөрлүүдийг харахын тулд тохиргоо руу очно уу"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Танай админ шинэчилсэн.\nОлгосон зөвшөөрлийг харахын тулд тохиргоо руу очно уу"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Таны админ устгасан"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батарей хэмнэгч нь Бараан загварыг асааж, дэвсгэрийн үйл ажиллагаа, зарим визуал эффект, тодорхой онцлогууд болон зарим сүлжээний холболтыг хязгаарлах эсвэл унтраана."</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index c37884d4473c..6f741d7b77b9 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करण्यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करण्यापूर्वी संकेतशब्दासाठी विचारा"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"तुमच्या ॲडमिनने इंस्टॉल केले आहे.\nदिलेल्या परवानग्या पाहण्यासाठी सेटिंग्जवर जा"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"तुमच्या ॲडमिनने अपडेट केले आहे.\nदिलेल्या परवानग्या पाहण्यासाठी सेटिंग्जवर जा"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"आपल्या प्रशासकाने हटवले"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ओके"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"बॅटरी सेव्हर गडद थीम सुरू करते आणि बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट, ठरावीक वैशिष्ट्ये व काही नेटवर्क कनेक्शन मर्यादित किंवा बंद करते."</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index d675246df729..4b2bb4da911e 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Minta corak buka kunci sebelum menyahsemat"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Minta kata laluan sebelum menyahsemat"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Dipasang oleh pentadbir anda.\nAkses tetapan untuk melihat kebenaran yang diberikan"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Dikemaskinikan oleh pentadbir anda.\nAkses tetapan untuk melihat kebenaran yang diberikan"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dipadamkan oleh pentadbir anda"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Penjimat Bateri menghidupkan tema Gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual, ciri tertentu dan sesetengah sambungan rangkaian."</string> @@ -2274,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Tatal"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Jeda"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Kedudukan"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Tatal Ke Atas"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Tatal Ke Bawah"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Tatal Ke Kiri"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Tatal ke Kanan"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Keluar Daripada Mod Tatal"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Tatal Panel"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah diletakkan dalam baldi TERHAD"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"menghantar imej"</string> @@ -2493,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"Kerja 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"Ujian"</string> <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"Mengawas"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil kerja"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ruang persendirian"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 1a5bc7af86ca..52421557f296 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ပင်မဖြုတ်မီ လော့ခ်ဖွင့်ပုံစံကို မေးရန်"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"သင့်စီမံခန့်ခွဲသူက ထည့်သွင်းထားသည်။\nပေးထားသည့် ခွင့်ပြုချက်များကို ကြည့်ရန် ဆက်တင်များသို့ သွားပါ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"သင့်စီမံခန့်ခွဲသူက အပ်ဒိတ်လုပ်ထားသည်။\nပေးထားသည့် ခွင့်ပြုချက်များကို ကြည့်ရန် ဆက်တင်များသို့ သွားပါ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"သင်၏ စီမံခန့်ခွဲသူက ဖျက်လိုက်ပါပြီ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ဖန်တီးပြသချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string> @@ -2274,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"လှိမ့်ရန်"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ခဏရပ်ရန်"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"နေရာ"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"အပေါ်သို့ လှိမ့်ရန်"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"အောက်သို့ လှိမ့်ရန်"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ဘယ်ဘက်သို့ လှိမ့်ရန်"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ညာဘက်သို့ လှိမ့်ရန်"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"လှိမ့်ရန်မုဒ်မှ ထွက်ရန်"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"အကန့်ကို လှိမ့်ခြင်း"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ကို တားမြစ်ထားသော သိမ်းဆည်းမှုအတွင်းသို့ ထည့်ပြီးပါပြီ"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>-"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ပုံပို့ထားသည်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 4b44dd6c67ce..3dca9b927c10 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Krev opplåsingsmønster for å løsne apper"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Krev passord for å løsne apper"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Installert av administratoren din.\nGå til innstillingene for å se hvilke tillatelser som er gitt"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Oppdatert av administratoren din.\nGå til innstillingene for å se hvilke tillatelser som er gitt"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet av administratoren din"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterisparing slår på mørkt tema og begrenser eller slår av bakgrunnsaktivitet, enkelte visuelle effekter, noen funksjoner og noen nettverkstilkoblinger."</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 16e48d547a55..13c98551b8ca 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1819,9 +1819,9 @@ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। ३ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"फोनको माइक प्रयोग गर्ने हो?"</string> - <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"श्रवण यन्त्रको माइक प्रयोग गर्ने हो?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"अझ राम्रो आवाज सुनाउन वा तपाईंको श्रवण यन्त्रको ब्याट्री कम भएका खण्डमा। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"तपाईं ह्यान्ड्सफ्री तरिकाले कल गर्न आफ्नो श्रवण यन्त्रको माइक्रोफोन प्रयोग गर्न सक्नुहुन्छ। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"हियरिङ एडको माइक प्रयोग गर्ने हो?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"अझ राम्रो आवाज सुनाउन वा तपाईंको हियरिङ एडको ब्याट्री कम भएका खण्डमा। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"तपाईं ह्यान्ड्सफ्री तरिकाले कल गर्न आफ्नो हियरिङ एडको माइक्रोफोन प्रयोग गर्न सक्नुहुन्छ। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"बदल्नुहोस्"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिङ"</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गरिँदै छ…"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन गर्नअघि अनलक प्याटर्न माग्नुहोस्"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"यो प्याकेज तपाईंका एड्मिनले इन्स्टल गर्नुभएको हो।\nप्रदान गरिएका अनुमतिसम्बन्धी जानकारी हेर्न सेटिङमा जानुहोस्"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"यो प्याकेज तपाईंका एड्मिनले अपडेट गर्नुभएको हो।\nकुन कुन अनुमति दिइएका छन् भन्ने कुरा हेर्न सेटिङमा जानुहोस्"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"तपाईंका प्रशासकले मेट्नुभएको"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ठिक छ"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ब्याट्री सेभरले अँध्यारो थिम अन गर्छ र ब्याकग्राउन्डमा हुने क्रियाकलाप, केही भिजुअल इफेक्ट, निश्चित सुविधा र केही नेटवर्क कनेक्सनहरू अफ गर्छ वा सीमित रूपमा मात्र चल्न दिन्छ।"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 11c40fdbfce4..f5e3831a6032 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ontgrendelingspatroon vragen om app los te maken"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vraag wachtwoord voor losmaken"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Geïnstalleerd door je beheerder.\nGa naar instellingen om verleende rechten te bekijken."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Geüpdatet door je beheerder.\nGa naar instellingen om verleende rechten te bekijken."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Verwijderd door je beheerder"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet."</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index eca778a24c8a..eee243f3f47a 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1820,7 +1820,7 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ଫୋନ ମାଇକକୁ ସୁଇଚ କରିବେ?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକକୁ ସୁଇଚ କରିବେ?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ଭଲ ସାଉଣ୍ଡ ପାଇଁ କିମ୍ବା ଯଦି ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ବେଟେରୀ କମ ଥିଲେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ଭଲ ସାଉଣ୍ଡ ପାଇଁ କିମ୍ବା ଯଦି ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ରର ବେଟେରୀ କମ ଥାଏ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string> <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ହେଣ୍ଡସ-ଫ୍ରି କଲିଂ ପାଇଁ ଆପଣ ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକ୍ରୋଫୋନ ବ୍ୟବହାର କରିପାରିବେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ସୁଇଚ କରନ୍ତୁ"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ସେଟିଂସ"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ଅନପିନ୍ କରିବା ପୂର୍ବରୁ ଲକ୍ ଖୋଲିବା ପାଟର୍ନ ପଚାରନ୍ତୁ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ଅନପିନ୍ କରିବା ପୂର୍ବରୁ ପାସ୍ୱର୍ଡ ପଚାରନ୍ତୁ"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଇନଷ୍ଟଲ କରାଯାଇଛି।\nଅନୁମୋଦିତ ଅମୁମତିଗୁଡ଼ିକ ଭ୍ୟୁ କରିବା ପାଇଁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅପଡେଟ କରାଯାଇଛି।\nଅନୁମୋଦିତ ଅମୁମତିଗୁଡ଼ିକ ଭ୍ୟୁ କରିବା ପାଇଁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ଆପଣଙ୍କ ଆଡମିନ୍ ଡିଲିଟ୍ କରିଛନ୍ତି"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ଠିକ ଅଛି"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ବେଟେରୀ ସେଭର ଗାଢ଼ା ଥିମକୁ ଚାଲୁ କରେ ଏବଂ ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ ଇଫେକ୍ଟ, କିଛି ଫିଚର ଏବଂ କିଛି ନେଟୱାର୍କ ସଂଯୋଗକୁ ସୀମିତ କିମ୍ବା ବନ୍ଦ କରେ।"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 2da2a608bf97..6632fb0f1354 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ।\nਦਿੱਤੀਆਂ ਗਈਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ।\nਦਿੱਤੀਆਂ ਗਈਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ਠੀਕ ਹੈ"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ਬੈਟਰੀ ਸੇਵਰ ਗੂੜ੍ਹੇ ਥੀਮ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ਟੀਗਤ ਪ੍ਰਭਾਵਾਂ, ਕੁਝ ਖਾਸ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਅਤੇ ਕੁਝ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨਾਂ ਨੂੰ ਸੀਮਤ ਜਾਂ ਬੰਦ ਕਰਦਾ ਹੈ।"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 730429da67d2..2cdac419ab0d 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1967,8 +1967,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Aby odpiąć, poproś o wzór odblokowania"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Aby odpiąć, poproś o hasło"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Zainstalowany przez administratora.\nOtwórz ustawienia, aby wyświetlić przyznane uprawnienia"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Zaktualizowany przez administratora.\nAby zobaczyć przyznane uprawnienia, przejdź do ustawień"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Usunięty przez administratora"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne, pewne funkcje oraz wybrane połączenia sieciowe."</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index cea3b73b2070..52dc72c2c280 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Atualizado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 2951d482a490..a8400e2837a4 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -2274,18 +2274,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Deslocar"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posição"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Deslocar página para cima"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Deslocar página para baixo"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Deslocar página para a esquerda"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Deslocar página para a direita"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sair do modo de deslocamento"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Deslocar painel"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no contentor RESTRITO."</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviou uma imagem"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index cea3b73b2070..52dc72c2c280 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Atualizado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 19158cc47ae2..8ad6d02e6113 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicită mai întâi modelul pentru deblocare"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicită parola înainte de a anula fixarea"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalat de administrator.\nAccesează setările ca să vezi permisiunile acordate."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Instalat de administrator.\nAccesează setările ca să vezi permisiunile acordate"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Șters de administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Economisirea bateriei activează tema întunecată și restricționează sau dezactivează activitatea în fundal, unele efecte vizuale, alte funcții și câteva conexiuni la rețea."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 136f76ae55ce..0ee25426bbf6 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1967,8 +1967,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запрашивать графический ключ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запрашивать пароль"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Установлено администратором.\nЧтобы посмотреть предоставленные разрешения, перейдите в настройки."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Обновлено администратором.\nЧтобы посмотреть предоставленные разрешения, перейдите в настройки."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Удалено администратором"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"В режиме энергосбережения включается тёмная тема, ограничиваются или отключаются фоновые процессы, а также некоторые визуальные эффекты, часть функций и сетевых подключений."</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 7a4de0eca678..0d3cd7e4979a 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ගැලවීමට පෙර මුරපදය විමසන්න"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"ඔබේ පරිපාලකයා විසින් ස්ථාපන කරනු ලබයි.\nදෙන ලද අවසර බැලීමට සැකසීම් වෙත යන්න"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"ඔබේ පරිපාලක විසින් යාවත්කාලීන කරන ලදි.\n ලබා දී ඇති අවසර බැලීමට සැකසීම් වෙත යන්න"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"ඔබගේ පරිපාලක මඟින් මකා දමා ඇත"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"හරි"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"බැටරි සුරැකුම අඳුරු තේමාව ක්රියාත්මක කර පසුබිම් ක්රියාකාරකම්, සමහර දෘශ්ය ප්රයෝග, යම් විශේෂාංග සහ සමහර ජාල සම්බන්ධතා සීමා හෝ ක්රියාවිරහිත කරයි."</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index c47ce658c1a8..e3855d1a6790 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1822,8 +1822,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Chcete prepnúť na mikrofón telefónu?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Chcete prepnúť na mikrofón načúvadla?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Keď chcete zlepšiť zvuk alebo ak je batéria načúvadla slabá. Týmto iba prepnete mikrofón počas hovoru."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Volať handsfree môžete pomocou mikrofónu načúvadla. Týmto iba prepnete mikrofón počas hovoru."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pre lepší zvuk alebo ak je batéria načúvadla takmer vybitá. Mikrofón sa prepne iba na čas hovoru."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Pomocou mikrofónu načúvadla môžete volať handsfree. Mikrofón sa prepne iba na čas hovoru."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prepnúť"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavenia"</string> <string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 07cb71c1b317..b0ebb5f073b7 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1821,9 +1821,9 @@ <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. S tremi prsti povlecite navzgor z dna zaslona in hitro spustite."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povečava"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite preklopiti na mikrofon telefona?"</string> - <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite preklopiti na mikrofon za slušni aparat?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite preklopiti na mikrofon slušnega aparata?"</string> <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za boljši zvok ali pri skoraj prazni bateriji slušnega aparata. S tem preklopite mikrofon samo med klicem."</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon za slušni aparat lahko uporabljate za prostoročno klicanje. S tem preklopite mikrofon samo med klicem."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnega aparata lahko uporabljate za prostoročno klicanje. S tem preklopite mikrofon samo med klicem."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Preklopi"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavitve"</string> <string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string> @@ -2275,18 +2275,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Drsenje"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Začasna zaustavitev"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Položaj"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Pomik gor"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Pomik dol"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Pomik levo"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Pomik desno"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izhod iz načina pomikanja"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Podokno za pomikanje"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je bil dodan v segment OMEJENO"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslal(-a) sliko"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 1b3feedaeccb..0f99307da7e3 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Kërko motivin e shkyçjes para heqjes së gozhdimit"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Kërko fjalëkalim para heqjes nga gozhdimi."</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Instaluar nga administratori.\nShko te cilësimet për të shikuar lejet e dhëna"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Përditësuar nga administratori.\nShko te cilësimet për të shikuar lejet e dhëna"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Fshirë nga administratori"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Në rregull"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"\"Kursyesi i baterisë\" aktivizon \"Temën e errët\" dhe kufizon ose çaktivizon aktivitetin në sfond, disa efekte vizuale, veçori të caktuara dhe disa lidhje të rrjetit."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 24624f7e479f..4827c0cc3265 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1966,8 +1966,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Ажурирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 2a920b235335..31f5592ecaad 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Omba mchoro wa kufungua kabla hujabandua"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Omba nenosiri kabla hujabandua"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Kimewekwa na msimamizi wako.\nNenda kwenye mipangilio ili uone ruhusa zilizotolewa"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Imesasishwa na msimamizi wako.\nNenda kwenye mipangilio ili uone ruhusa zilizotolewa"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Imefutwa na msimamizi wako"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Sawa"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Kiokoa Betri huwasha Mandhari meusi na kudhibiti au kuzima shughuli za chinichini, baadhi ya madoido yanayoonekana, vipengele fulani na baadhi ya miunganisho ya mtandao."</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 1fade556f421..36b82d99aded 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"உங்கள் நிர்வாகி நிறுவியுள்ளார்.\nவழங்கப்பட்டுள்ள அனுமதிகளை பார்க்க அமைப்புகளுக்குச் செல்லவும்"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்.\nவழங்கப்பட்டுள்ள அனுமதிகளைப் பார்க்க அமைப்புகளுக்குச் செல்லவும்"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"உங்கள் நிர்வாகி நீக்கியுள்ளார்"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"சரி"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"பேட்டரி சேமிப்பான் அம்சம் டார்க் தீமை இயக்குவதோடு பின்னணிச் செயல்பாடு, சில விஷுவல் எஃபக்ட்கள், குறிப்பிட்ட அம்சங்கள், சில நெட்வொர்க் இணைப்புகள் ஆகியவற்றைக் கட்டுப்படுத்தும் அல்லது முடக்கும்."</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 4f6eaf3b2307..74ab1e870ccb 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1820,7 +1820,7 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మ్యాగ్నిఫికేషన్"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ఫోన్ మైక్కు మారాలా?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"వినికిడి పరికరం మైక్కు మారాలా?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"మెరుగైన సౌండ్ కోసం లేదా మీ వినికిడి పరికరం బ్యాటరీ తక్కువగా ఉన్నప్పుడు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్ను మారుస్తుంది."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"మెరుగైన సౌండ్ కావాల్సినప్పుడు లేదా మీ వినికిడి పరికరం బ్యాటరీ తక్కువగా ఉన్నప్పుడు ఇది ఉపయోగపడుతుంది. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్ను మారుస్తుంది."</string> <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"హ్యాండ్స్-ఫ్రీ కాలింగ్ కోసం మీరు మీ వినికిడి పరికరాన్ని ఉపయోగించవచ్చు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్ను మారుస్తుంది."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"మారండి"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"సెట్టింగ్లు"</string> @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"స్క్రోల్ చేయండి"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"పాజ్ చేయండి"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"స్థానం"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"పైకి స్క్రోల్ చేయండి"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"కిందికి స్క్రోల్ చేయండి"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ఎడమ వైపునకు స్క్రోల్ చేయండి"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"కుడి వైపునకు స్క్రోల్ చేయండి"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"స్క్రోల్ మోడ్ నుండి ఎగ్జిట్ అవ్వండి"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ప్యానెల్కు స్క్రోల్ చేయండి"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> పరిమితం చేయబడిన బకెట్లో ఉంచబడింది"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ఇమేజ్ను పంపారు"</string> @@ -2492,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"ఆఫీస్ 3"</string> <string name="profile_label_test" msgid="9168641926186071947">"పరీక్ష"</string> <string name="profile_label_communal" msgid="8743921499944800427">"కమ్యూనల్"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"పర్యవేక్షిస్తున్నారు"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"వర్క్ ప్రొఫైల్"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ప్రైవేట్ స్పేస్"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"క్లోన్"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index dfaa061ba093..8119d7d2bb2a 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -962,7 +962,7 @@ <string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string> <string name="eventTypeCustom" msgid="3257367158986466481">"Özel"</string> <string name="eventTypeBirthday" msgid="7770026752793912283">"Doğum günü"</string> - <string name="eventTypeAnniversary" msgid="4684702412407916888">"Yıldönümü"</string> + <string name="eventTypeAnniversary" msgid="4684702412407916888">"Yıl dönümü"</string> <string name="eventTypeOther" msgid="530671238533887997">"Diğer"</string> <string name="emailTypeCustom" msgid="1809435350482181786">"Özel"</string> <string name="emailTypeHome" msgid="1597116303154775999">"Ev"</string> @@ -1820,7 +1820,7 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Büyütme"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofonuna geçilsin mi?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"İşitme cihazı mikrofonuna geçilsin mi?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Daha iyi ses kalitesi için veya işitme cihazınızın pili azaldığında Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Daha iyi ses kalitesi için veya işitme cihazınızın pili azaldığında. Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string> <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Eller serbest modunda arama yapmak için işitme cihazı mikrofonunu kullanabilirsiniz. Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Geçiş yap"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ayarlar"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Sabitlemeyi kaldırmadan önce şifre sor"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Yöneticiniz tarafından yüklendi.\nVerilen izinleri görüntülemek için ayarlara gidin"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Yöneticiniz tarafından güncellendi.\nVerilen izinleri görüntülemek için ayarlara gidin"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Yöneticiniz tarafından silindi"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Tamam"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Pil Tasarrufu, Koyu temayı açıp arka plan etkinliğini, bazı görsel efektleri, belirli özellikleri ve bazı ağ bağlantılarını sınırlandırır veya kapatır."</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 34dda976f1bc..cda2af43ef12 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1967,8 +1967,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитувати ключ розблокування перед відкріпленням"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитувати пароль перед відкріпленням"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Установлено адміністратором.\nПерейдіть у налаштування, щоб переглянути надані дозволи."</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Оновлено адміністратором.\nПерейдіть у налаштування, щоб переглянути надані дозволи."</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Видалено адміністратором"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"У режимі енергозбереження вмикається темна тема й обмежуються чи вимикаються дії у фоновому режимі, а також деякі візуальні ефекти, функції та з’єднання з мережами."</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 31b5999b6f15..df87d192869c 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -21,7 +21,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="202579285008794431">"بائٹس"</string> - <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> + <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> <string name="untitled" msgid="3381766946944136678">">بلا عنوان<"</string> <string name="emptyPhoneNumber" msgid="5812172618020360048">"(کوئی فون نمبر نہیں ہے)"</string> <string name="unknownName" msgid="7078697621109055330">"نامعلوم"</string> @@ -2273,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"اسکرول کریں"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"موقوف کریں"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"پوزیشن"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"اوپر اسکرول کریں"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"نیچے اسکرول کریں"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"بائیں اسکرول کریں"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"دائیں اسکرول کریں"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"اسکرول موڈ سے باہر نکلیں"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"اسکرول پینل"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> کو پابند کردہ بکٹ میں رکھ دیا گیا ہے"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ایک تصویر بھیجی"</string> @@ -2492,8 +2486,7 @@ <string name="profile_label_work_3" msgid="4834572253956798917">"تیسری دفتری پروفائل"</string> <string name="profile_label_test" msgid="9168641926186071947">"ٹیسٹ"</string> <string name="profile_label_communal" msgid="8743921499944800427">"کمیونل"</string> - <!-- no translation found for profile_label_supervising (5649312778545745371) --> - <skip /> + <string name="profile_label_supervising" msgid="5649312778545745371">"نگرانی کرنے والی"</string> <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"دفتری پروفائل"</string> <string name="accessibility_label_private_profile" msgid="1436459319135548969">"پرائیویٹ اسپیس"</string> <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"کلون"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 35c35ac6d90b..fc2bd4b605d1 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1818,9 +1818,9 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 2 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 3 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string> - <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofoniga almashtirilsinmi?"</string> - <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Eshitish moslamasi mikrofoniga almashtirilsinmi?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Tovush yaxshilanishi uchun yoki eshitish moslamasi batareyasi quvvati kam boʻlsa. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofoniga almashilsinmi?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Eshitish moslamasi mikrofoniga almashilsinmi?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Tovush sifati sizni qoniqtirmasa yoki eshitish moslamasi batareyasi quvvati kamligida telefon mikrofonidan foydalanishingiz mumkin. Mikrofon faqat chaqiruv vaqtida almashadi."</string> <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Garniturali chaqiruv uchun eshitish moslamasi mikrofonidan foydalanish mumkin. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Almashtirish"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Sozlamalar"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Yechishdan oldin grafik kalit so‘ralsin"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bo‘shatishdan oldin parol so‘ralsin"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Administrator oʻrnatgan.\nBerilgan ruxsatlarni koʻrish uchun sozlamalarni oching"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Administrator yangilagan.\nBerilgan ruxsatlarni koʻrish uchun sozlamalarni oching"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administrator tomonidan o‘chirilgan"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Quvvat tejash funksiyasi Tungi mavzuni va cheklovlarni yoqadi hamda fondagi harakatlar, vizual effektlar, ayrim funksiyalar va tarmoq aloqalari kabi boshqa funksiyalarni faolsizlantiradi yoki cheklaydi."</string> @@ -2274,18 +2273,12 @@ <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Aylantirish"</string> <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauza"</string> <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Joylashuvi"</string> - <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) --> - <skip /> - <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) --> - <skip /> + <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Tepaga varaqlash"</string> + <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Pastga varaqlash"</string> + <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Chapga varaqlash"</string> + <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Oʻngga varaqlash"</string> + <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Varaqlash rejimidan chiqish"</string> + <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Varaqlash paneli"</string> <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> cheklangan turkumga joylandi"</string> <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string> <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"rasm yuborildi"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 626625f85d40..4141af07dc8b 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Hỏi hình mở khóa trước khi bỏ ghim"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Hỏi mật khẩu trước khi bỏ ghim"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Do quản trị viên của bạn cài đặt.\nChuyển đến phần cài đặt để xem các quyền được cấp"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Do quản trị viên của bạn cập nhật.\nChuyển đến phần cài đặt để xem các quyền được cấp"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Do quản trị viên của bạn xóa"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Trình tiết kiệm pin sẽ bật Giao diện tối, đồng thời hạn chế hoặc tắt hoạt động chạy trong nền, một số hiệu ứng hình ảnh, các tính năng nhất định và một số đường kết nối mạng."</string> diff --git a/core/res/res/values-w192dp/dimens_watch.xml b/core/res/res/values-w192dp/dimens_watch.xml new file mode 100644 index 000000000000..a3730aaf7961 --- /dev/null +++ b/core/res/res/values-w192dp/dimens_watch.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<resources> + <!-- watch's indeterminate progress bar dimens based on the current screen size --> + <dimen name="loader_horizontal_min_width_watch">67dp</dimen> + <dimen name="loader_horizontal_min_height_watch">15dp</dimen> +</resources> diff --git a/core/res/res/values-w204dp/dimens_watch.xml b/core/res/res/values-w204dp/dimens_watch.xml new file mode 100644 index 000000000000..3509474c5c2e --- /dev/null +++ b/core/res/res/values-w204dp/dimens_watch.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<resources> + <!-- watch's indeterminate progress bar dimens based on the current screen size --> + <dimen name="loader_horizontal_min_width_watch">70dp</dimen> + <dimen name="loader_horizontal_min_height_watch">15dp</dimen> +</resources> diff --git a/core/res/res/values-w216dp/dimens_watch.xml b/core/res/res/values-w216dp/dimens_watch.xml new file mode 100644 index 000000000000..96d80abb5988 --- /dev/null +++ b/core/res/res/values-w216dp/dimens_watch.xml @@ -0,0 +1,21 @@ +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources> + <!-- watch's indeterminate progress bar dimens based on the current screen size --> + <dimen name="loader_horizontal_min_width_watch">74dp</dimen> + <dimen name="loader_horizontal_min_height_watch">16dp</dimen> +</resources>
\ No newline at end of file diff --git a/core/res/res/values-w228dp/dimens_watch.xml b/core/res/res/values-w228dp/dimens_watch.xml new file mode 100644 index 000000000000..960e3228ee0b --- /dev/null +++ b/core/res/res/values-w228dp/dimens_watch.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<resources> + <!-- watch's indeterminate progress bar dimens based on the current screen size --> + <dimen name="loader_horizontal_min_width_watch">78dp</dimen> + <dimen name="loader_horizontal_min_height_watch">16dp</dimen> +</resources> diff --git a/core/res/res/values-w240dp/dimens_watch.xml b/core/res/res/values-w240dp/dimens_watch.xml new file mode 100644 index 000000000000..d8478a872ae1 --- /dev/null +++ b/core/res/res/values-w240dp/dimens_watch.xml @@ -0,0 +1,21 @@ +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources> + <!-- watch's indeterminate progress bar dimens based on the current screen size --> + <dimen name="loader_horizontal_min_width_watch">82dp</dimen> + <dimen name="loader_horizontal_min_height_watch">17dp</dimen> +</resources> diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml index ef5875eff06f..57a09ea34ba1 100644 --- a/core/res/res/values-watch/config.xml +++ b/core/res/res/values-watch/config.xml @@ -114,4 +114,7 @@ <!-- By default ActivityOptions#makeScaleUpAnimation is only used between activities. This config enables OEMs to support its usage across tasks.--> <bool name="config_enableCrossTaskScaleUpAnimation">true</bool> + + <!-- The amount of friction applied to scrolls and flings. --> + <item name="config_scrollFriction" format="float" type="dimen">0.023</item> </resources> diff --git a/core/res/res/values-watch/styles_device_defaults.xml b/core/res/res/values-watch/styles_device_defaults.xml index fb7dbb0660c5..eeb66e7cf6a8 100644 --- a/core/res/res/values-watch/styles_device_defaults.xml +++ b/core/res/res/values-watch/styles_device_defaults.xml @@ -42,5 +42,8 @@ <item name="indeterminateOnly">false</item> <!-- Use Wear Material3 ring shape as default determinate drawable --> <item name="progressDrawable">@drawable/progress_ring_watch</item> + <item name="indeterminateDrawable">@drawable/loader_horizontal_watch</item> + <item name="android:minWidth">@dimen/loader_horizontal_min_width_watch</item> + <item name="android:minHeight">@dimen/loader_horizontal_min_height_watch</item> </style> </resources> diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml index 60aec5342b4f..4738d20cdede 100644 --- a/core/res/res/values-watch/themes_device_defaults.xml +++ b/core/res/res/values-watch/themes_device_defaults.xml @@ -48,6 +48,9 @@ a similar way. <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item> <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item> <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item> + + <!-- Material3 default delay before scroll bar fading animation. --> + <item name="scrollbarDefaultDelayBeforeFade">1000</item> </style> <!-- Variant of {@link #Theme_DeviceDefault} with no action bar --> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 921a464c434e..95dd35fcb0dd 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1820,8 +1820,8 @@ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大功能"</string> <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切换为手机麦克风吗?"</string> <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切换为助听器麦克风吗?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音质,或在助听器电池电量不足时使用。此操作只会切换通话期间的麦克风。"</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"您可以使用助听器麦克风进行免提通话。此操作只会切换通话期间的麦克风。"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音质,或在助听器电池电量不足时使用。系统仅会在通话期间切换麦克风。"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"您可以使用助听器麦克风进行免提通话。系统只会在通话期间切换麦克风。"</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切换"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"设置"</string> <string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定前要求绘制解锁图案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消时要求输入密码"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"由您的管理员安装。\n前往设置可查看已授予的权限"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"由您的管理员更新。\n前往设置可查看已授予的权限"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由您的管理员删除"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"确定"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"在省电模式下,系统会启用深色主题,并限制或关闭后台活动、某些视觉效果、特定功能和部分网络连接。"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 8681d036948a..b956da1e856e 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1818,10 +1818,10 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快速鍵時,就會開啟此功能。請用 2 隻手指從螢幕底部向上滑動並快速放開。"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快速鍵時,就會開啟此功能。請用 3 隻手指從螢幕底部向上滑動並快速放開。"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string> - <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切換至手機麥克風嗎?"</string> - <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切換至助聽器麥克風嗎?"</string> - <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音質,也在助聽器電量不足時適用。此操作只會切換通話期間的麥克風。"</string> - <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"你可使用助聽器麥克風進行免提通話。此操作只會切換通話期間的麥克風。"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要轉用手機麥克風嗎?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要轉用助聽器麥克風嗎?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"這樣可改善音質,助聽器電量不足時亦適用。系統只會在通話期間切換麥克風。"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"你可使用助聽器麥克風進行免提通話。系統只會在通話期間切換麥克風。"</string> <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切換"</string> <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string> <string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"已由你的管理員安裝。\n請前往設定查看已授予的權限"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"已由你的管理員更新。\n請前往設定查看已授予的權限"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"好"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"「慳電模式」會開啟深色主題背景,並限制或關閉背景活動、部分視覺效果、特定功能和部分網絡連線。"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 21e9113bc9a0..f9abe0e69a46 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須畫出解鎖圖案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"這是管理員安裝的套件。\n你可以前往設定查看授予的權限"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"管理員已更新套件。\n你可以前往設定查看授予的權限"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"省電模式會開啟深色主題,並限制或關閉背景活動、某些視覺效果、特定功能和部分網路連線。"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 695f3198c90b..4292eab29a16 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1965,8 +1965,7 @@ <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string> <string name="package_installed_device_owner" msgid="8684974629306529138">"Kufakwe ngumphathi wakho.\nIya kumasethingi ukuze ubuke izimvume ezinikeziwe"</string> - <!-- no translation found for package_updated_device_owner (7770195449213776218) --> - <skip /> + <string name="package_updated_device_owner" msgid="7770195449213776218">"Kubuyekezwe ngumphathi wakho.\nIya kumasethingi ukuze ubuke izimvume ezinikeziwe"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Kususwe umlawuli wakho"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"KULUNGILE"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Isilondolozi Sebhethri sivula ingqikithi emnyama futhi sibeke umkhawulo noma sivale umsebenzi ongemuva, imiphumela ethile yokubuka, izici ezithile, nokuxhumeka okuthile kwenethiwekhi."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 7a38dce296de..e47adc90fc7a 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2831,6 +2831,10 @@ <!-- Whether dreams are disabled when ambient mode is suppressed. --> <bool name="config_dreamsDisabledByAmbientModeSuppressionConfig">false</bool> + <!-- The default for the setting that controls when to auto-start hub mode. + 0 means "never" --> + <integer name="config_whenToStartHubModeDefault">0</integer> + <!-- The duration in milliseconds of the dream opening animation. --> <integer name="config_dreamOpenAnimationDuration">250</integer> <!-- The duration in milliseconds of the dream closing animation. --> @@ -6108,6 +6112,9 @@ <!-- Whether to default to an expanded list of users on the lock screen user switcher. --> <bool name="config_expandLockScreenUserSwitcher">false</bool> + <!-- Help URI, action disabled by advanced protection [DO NOT TRANSLATE] --> + <string name="config_help_url_action_disabled_by_advanced_protection" translatable="false"></string> + <!-- Toasts posted from these packages will be shown to the current user, regardless of the user the process belongs to. This is useful for packages that run under a single user but serve multiple users, e.g. the system. diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 6e540833bc46..c0d2779f3a31 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -295,6 +295,11 @@ <!-- The margin of the notification action list at the bottom in the 2025 redesign --> <dimen name="notification_2025_action_list_margin_bottom">6dp</dimen> + <!-- The minimum height of the notification action container, to act as a bottom padding for the + notification when there are no actions. This should always be equal to + notification_2025_margin - notification_2025_action_list_margin_bottom. --> + <dimen name="notification_2025_action_list_min_height">10dp</dimen> + <!-- The overall height of the emphasized notification action --> <dimen name="notification_action_emphasized_height">48dp</dimen> @@ -333,9 +338,9 @@ <!-- The spacing between the content and the header text above it, scaling with text size. This value is chosen so that, taking into account the text spacing for both the text in the - top line and the text in the content, the distance between them is 4dp with the default + top line and the text in the content, the distance between them is ~2dp with the default screen configuration (and will grow accordingly for larger font sizes) --> - <dimen name="notification_2025_content_margin_top">10sp</dimen> + <dimen name="notification_2025_content_margin_top">8sp</dimen> <!-- height of the content margin that is applied at the end of the notification content --> <dimen name="notification_content_margin">20dp</dimen> @@ -445,6 +450,8 @@ <!-- the size of the notification close button --> <dimen name="notification_close_button_size">16dp</dimen> + <dimen name="notification_close_button_padding">2dp</dimen> + <!-- Margin for all notification content --> <dimen name="notification_2025_margin">16dp</dimen> @@ -516,6 +523,9 @@ <!-- The spacing between messages in Notification.MessagingStyle --> <dimen name="notification_messaging_spacing">6dp</dimen> + <!-- The spacing between messages in Notification.MessagingStyle (2025 redesign version) --> + <dimen name="notification_2025_messaging_spacing">14dp</dimen> + <!-- The spacing between messages in Notification.MessagingStyle --> <dimen name="notification_messaging_spacing_conversation_group">24dp</dimen> diff --git a/core/res/res/values/dimens_watch.xml b/core/res/res/values/dimens_watch.xml index 7462b733b0ae..a8ed666d13fe 100644 --- a/core/res/res/values/dimens_watch.xml +++ b/core/res/res/values/dimens_watch.xml @@ -61,4 +61,8 @@ <dimen name="disabled_alpha_wear_material3">0.12</dimen> <!-- Alpha transparency applied to elements which are considered primary (e.g. primary text) --> <dimen name="primary_content_alpha_wear_material3">0.38</dimen> + + <!-- watch's indeterminate progress bar dimens --> + <dimen name="loader_horizontal_min_width_watch">76dp</dimen> + <dimen name="loader_horizontal_min_height_watch">14dp</dimen> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 922d59dfcfe0..a37ca2847638 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2072,6 +2072,7 @@ <java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" /> <java-symbol type="bool" name="config_keepDreamingWhenUnplugging" /> <java-symbol type="bool" name="config_glanceableHubEnabled" /> + <java-symbol type="integer" name="config_whenToStartHubModeDefault" /> <java-symbol type="integer" name="config_keyguardDrawnTimeout" /> <java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" /> <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" /> @@ -3243,6 +3244,7 @@ <java-symbol type="id" name="expand_button_pill_colorized_layer" /> <java-symbol type="id" name="expand_button_number" /> <java-symbol type="id" name="expand_button_icon" /> + <java-symbol type="id" name="close_button_pill_colorized_layer" /> <java-symbol type="id" name="alternate_expand_target" /> <java-symbol type="id" name="notification_header" /> <java-symbol type="id" name="notification_top_line" /> @@ -5963,6 +5965,8 @@ <!-- Device CMF Theming Settings --> <java-symbol type="array" name="theming_defaults" /> + <java-symbol type="string" name="config_help_url_action_disabled_by_advanced_protection" /> + <!-- Advanced Protection Service USB feature --> <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_title" /> <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_text" /> diff --git a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java index 6d86bd209a3d..746ba9659c83 100644 --- a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java +++ b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; @MediumTest @@ -490,9 +491,24 @@ public class AnimatorSetCallsTest { @Test public void testCancelOnPendingEndListener() throws Throwable { + testPendingEndListener(AnimatorSet::cancel); + } + + @Test + public void testEndOnPendingEndListener() throws Throwable { + testPendingEndListener(animatorSet -> { + // This verifies that isRunning() and isStarted() are true at last frame. + // Then the end() should invoke the end callback immediately. + if (animatorSet.isRunning() && animatorSet.isStarted()) { + animatorSet.end(); + } + }); + } + + private void testPendingEndListener(Consumer<AnimatorSet> finishOnLastFrame) throws Throwable { final CountDownLatch endLatch = new CountDownLatch(1); final Handler handler = new Handler(Looper.getMainLooper()); - final boolean[] endCalledRightAfterCancel = new boolean[2]; + final boolean[] endCalledImmediately = new boolean[2]; final AnimatorSet set = new AnimatorSet(); final ValueAnimatorTests.MyListener asListener = new ValueAnimatorTests.MyListener(); final ValueAnimatorTests.MyListener vaListener = new ValueAnimatorTests.MyListener(); @@ -502,9 +518,9 @@ public class AnimatorSetCallsTest { va.addUpdateListener(animation -> { if (animation.getAnimatedFraction() == 1f) { handler.post(() -> { - set.cancel(); - endCalledRightAfterCancel[0] = vaListener.endCalled; - endCalledRightAfterCancel[1] = asListener.endCalled; + finishOnLastFrame.accept(set); + endCalledImmediately[0] = vaListener.endCalled; + endCalledImmediately[1] = asListener.endCalled; endLatch.countDown(); }); } @@ -517,8 +533,8 @@ public class AnimatorSetCallsTest { try { handler.post(set::start); assertTrue(endLatch.await(1, TimeUnit.SECONDS)); - assertTrue(endCalledRightAfterCancel[0]); - assertTrue(endCalledRightAfterCancel[1]); + assertTrue(endCalledImmediately[0]); + assertTrue(endCalledImmediately[1]); } finally { ValueAnimator.setPostNotifyEndListenerEnabled(false); } diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java index a55909f0c193..89664fff979b 100644 --- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java +++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java @@ -44,6 +44,7 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) @MediumTest @@ -923,9 +924,25 @@ public class ValueAnimatorTests { @Test public void testCancelOnPendingEndListener() throws Throwable { + testPendingEndListener(ValueAnimator::cancel); + } + + @Test + public void testEndOnPendingEndListener() throws Throwable { + testPendingEndListener(animator -> { + // This verifies that isRunning() and isStarted() are true at last frame. + // Then the end() should invoke the end callback immediately. + if (animator.isRunning() && animator.isStarted()) { + animator.end(); + } + }); + } + + private void testPendingEndListener(Consumer<ValueAnimator> finishOnLastFrame) + throws Throwable { + final boolean[] endCalledImmediately = new boolean[1]; final CountDownLatch endLatch = new CountDownLatch(1); final Handler handler = new Handler(Looper.getMainLooper()); - final boolean[] endCalledRightAfterCancel = new boolean[1]; final MyListener listener = new MyListener(); final ValueAnimator va = new ValueAnimator(); va.setFloatValues(0f, 1f); @@ -933,8 +950,8 @@ public class ValueAnimatorTests { va.addUpdateListener(animation -> { if (animation.getAnimatedFraction() == 1f) { handler.post(() -> { - va.cancel(); - endCalledRightAfterCancel[0] = listener.endCalled; + finishOnLastFrame.accept(va); + endCalledImmediately[0] = listener.endCalled; endLatch.countDown(); }); } @@ -945,7 +962,7 @@ public class ValueAnimatorTests { try { handler.post(va::start); assertThat(endLatch.await(1, TimeUnit.SECONDS)).isTrue(); - assertThat(endCalledRightAfterCancel[0]).isTrue(); + assertThat(endCalledImmediately[0]).isTrue(); } finally { ValueAnimator.setPostNotifyEndListenerEnabled(false); } diff --git a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java index 62d89f6dc846..146b386e5a4b 100644 --- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java +++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java @@ -16,19 +16,37 @@ package android.app; +import static android.content.Intent.ACTION_MAIN; +import static android.content.Intent.CATEGORY_INFO; +import static android.content.Intent.CATEGORY_LAUNCHER; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; +import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.os.storage.VolumeInfo.STATE_MOUNTED; import static android.os.storage.VolumeInfo.STATE_UNMOUNTED; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager.ResolveInfoFlags; +import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; @@ -44,6 +62,7 @@ import com.android.internal.annotations.VisibleForTesting; import junit.framework.TestCase; +import org.mockito.ArgumentMatcher; import org.mockito.Mockito; import org.xmlpull.v1.XmlPullParser; @@ -102,14 +121,14 @@ public class ApplicationPackageManagerTest extends TestCase { sVolumes.add(sPrivateUnmountedVol); } - private static final class MockedApplicationPackageManager extends ApplicationPackageManager { + public static class MockedApplicationPackageManager extends ApplicationPackageManager { private boolean mForceAllowOnExternal = false; private boolean mAllow3rdPartyOnInternal = true; private HashMap<ApplicationInfo, Resources> mResourcesMap; public MockedApplicationPackageManager() { super(null, null); - mResourcesMap = new HashMap<ApplicationInfo, Resources>(); + mResourcesMap = new HashMap<>(); } public void setForceAllowOnExternal(boolean forceAllowOnExternal) { @@ -153,7 +172,7 @@ public class ApplicationPackageManagerTest extends TestCase { } private StorageManager getMockedStorageManager() { - StorageManager storageManager = Mockito.mock(StorageManager.class); + StorageManager storageManager = mock(StorageManager.class); Mockito.when(storageManager.getVolumes()).thenReturn(sVolumes); Mockito.when(storageManager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL)) .thenReturn(sInternalVol); @@ -190,7 +209,7 @@ public class ApplicationPackageManagerTest extends TestCase { sysAppInfo.flags = ApplicationInfo.FLAG_SYSTEM; StorageManager storageManager = getMockedStorageManager(); - IPackageManager pm = Mockito.mock(IPackageManager.class); + IPackageManager pm = mock(IPackageManager.class); MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); @@ -220,7 +239,7 @@ public class ApplicationPackageManagerTest extends TestCase { ApplicationInfo appInfo = new ApplicationInfo(); StorageManager storageManager = getMockedStorageManager(); - IPackageManager pm = Mockito.mock(IPackageManager.class); + IPackageManager pm = mock(IPackageManager.class); Mockito.when(pm.isPackageDeviceAdminOnAnyUser(Mockito.anyString())).thenReturn(false); MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); @@ -249,7 +268,7 @@ public class ApplicationPackageManagerTest extends TestCase { ApplicationInfo appInfo = new ApplicationInfo(); StorageManager storageManager = getMockedStorageManager(); - IPackageManager pm = Mockito.mock(IPackageManager.class); + IPackageManager pm = mock(IPackageManager.class); MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); appPkgMgr.setForceAllowOnExternal(true); @@ -291,15 +310,15 @@ public class ApplicationPackageManagerTest extends TestCase { public void testExtractPackageItemInfoAttributes_noMetaData() { final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); - final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class); + final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class); assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null, new int[]{})).isNull(); } public void testExtractPackageItemInfoAttributes_noParser() { final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); - final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class); - final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class); + final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class); + final ApplicationInfo applicationInfo = mock(ApplicationInfo.class); when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo); assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null, new int[]{})).isNull(); @@ -307,8 +326,8 @@ public class ApplicationPackageManagerTest extends TestCase { public void testExtractPackageItemInfoAttributes_noMetaDataXml() { final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); - final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class); - final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class); + final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class); + final ApplicationInfo applicationInfo = mock(ApplicationInfo.class); when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo); when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(null); assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null, @@ -318,9 +337,9 @@ public class ApplicationPackageManagerTest extends TestCase { public void testExtractPackageItemInfoAttributes_nonMatchingRootTag() throws Exception { final String rootTag = "rootTag"; final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); - final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class); - final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class); - final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class); + final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class); + final ApplicationInfo applicationInfo = mock(ApplicationInfo.class); + final XmlResourceParser parser = mock(XmlResourceParser.class); when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo); packageItemInfo.metaData = new Bundle(); @@ -334,11 +353,11 @@ public class ApplicationPackageManagerTest extends TestCase { public void testExtractPackageItemInfoAttributes_successfulExtraction() throws Exception { final String rootTag = "rootTag"; final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager(); - final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class); - final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class); - final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class); - final Resources resources = Mockito.mock(Resources.class); - final TypedArray attributes = Mockito.mock(TypedArray.class); + final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class); + final ApplicationInfo applicationInfo = mock(ApplicationInfo.class); + final XmlResourceParser parser = mock(XmlResourceParser.class); + final Resources resources = mock(Resources.class); + final TypedArray attributes = mock(TypedArray.class); when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo); packageItemInfo.metaData = new Bundle(); @@ -351,4 +370,123 @@ public class ApplicationPackageManagerTest extends TestCase { assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, rootTag, new int[]{})).isEqualTo(attributes); } + + public void testGetLaunchIntentForPackage_categoryInfoActivity_returnsIt() throws Exception { + String pkg = "com.some.package"; + int userId = 42; + ResolveInfo categoryInfoResolveInfo = new ResolveInfo(); + categoryInfoResolveInfo.activityInfo = new ActivityInfo(); + categoryInfoResolveInfo.activityInfo.packageName = pkg; + categoryInfoResolveInfo.activityInfo.name = "activity"; + Intent baseIntent = new Intent(ACTION_MAIN).setPackage(pkg); + + final MockedApplicationPackageManager pm = spy(new MockedApplicationPackageManager()); + doReturn(userId).when(pm).getUserId(); + doReturn(List.of(categoryInfoResolveInfo)) + .when(pm).queryIntentActivitiesAsUser( + eqIntent(new Intent(baseIntent).addCategory(CATEGORY_INFO)), + any(ResolveInfoFlags.class), + anyInt()); + doReturn( + List.of()) + .when(pm).queryIntentActivitiesAsUser( + eqIntent(new Intent(baseIntent).addCategory(CATEGORY_LAUNCHER)), + any(ResolveInfoFlags.class), + anyInt()); + + Intent intent = pm.getLaunchIntentForPackage(pkg, true); + + assertThat(intent).isNotNull(); + assertThat(intent.getComponent()).isEqualTo(new ComponentName(pkg, "activity")); + assertThat(intent.getCategories()).containsExactly(CATEGORY_INFO); + assertThat(intent.getFlags()).isEqualTo(FLAG_ACTIVITY_NEW_TASK); + verify(pm).queryIntentActivitiesAsUser( + eqIntent(new Intent(ACTION_MAIN).addCategory(CATEGORY_INFO).setPackage(pkg)), + eqResolveInfoFlags(MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE), + eq(userId)); + } + + public void testGetLaunchIntentForPackage_categoryLauncherActivity_returnsIt() { + String pkg = "com.some.package"; + int userId = 42; + ResolveInfo categoryLauncherResolveInfo1 = new ResolveInfo(); + categoryLauncherResolveInfo1.activityInfo = new ActivityInfo(); + categoryLauncherResolveInfo1.activityInfo.packageName = pkg; + categoryLauncherResolveInfo1.activityInfo.name = "activity1"; + ResolveInfo categoryLauncherResolveInfo2 = new ResolveInfo(); + categoryLauncherResolveInfo2.activityInfo = new ActivityInfo(); + categoryLauncherResolveInfo2.activityInfo.packageName = pkg; + categoryLauncherResolveInfo2.activityInfo.name = "activity2"; + Intent baseIntent = new Intent(ACTION_MAIN).setPackage(pkg); + + final MockedApplicationPackageManager pm = spy(new MockedApplicationPackageManager()); + doReturn(userId).when(pm).getUserId(); + doReturn(List.of()) + .when(pm).queryIntentActivitiesAsUser( + eqIntent(new Intent(baseIntent).addCategory(CATEGORY_INFO)), + any(ResolveInfoFlags.class), + anyInt()); + doReturn( + List.of(categoryLauncherResolveInfo1, categoryLauncherResolveInfo2)) + .when(pm).queryIntentActivitiesAsUser( + eqIntent(new Intent(baseIntent).addCategory(CATEGORY_LAUNCHER)), + any(ResolveInfoFlags.class), + anyInt()); + + Intent intent = pm.getLaunchIntentForPackage(pkg, true); + + assertThat(intent).isNotNull(); + assertThat(intent.getComponent()).isEqualTo(new ComponentName(pkg, "activity1")); + assertThat(intent.getCategories()).containsExactly(CATEGORY_LAUNCHER); + assertThat(intent.getFlags()).isEqualTo(FLAG_ACTIVITY_NEW_TASK); + } + + public void testGetLaunchIntentForPackage_noSuitableActivity_returnsNull() throws Exception { + String pkg = "com.some.package"; + int userId = 42; + + final MockedApplicationPackageManager pm = spy(new MockedApplicationPackageManager()); + doReturn(userId).when(pm).getUserId(); + doReturn(List.of()) + .when(pm).queryIntentActivitiesAsUser( + any(), + any(ResolveInfoFlags.class), + anyInt()); + + Intent intent = pm.getLaunchIntentForPackage(pkg, true); + + assertThat(intent).isNull(); + } + + /** Equality check for intents -- ignoring extras */ + private static Intent eqIntent(Intent wanted) { + return argThat( + new ArgumentMatcher<>() { + @Override + public boolean matches(Intent argument) { + return wanted.filterEquals(argument) + && wanted.getFlags() == argument.getFlags(); + } + + @Override + public String toString() { + return wanted.toString(); + } + }); + } + + private static ResolveInfoFlags eqResolveInfoFlags(long flagsWanted) { + return argThat( + new ArgumentMatcher<>() { + @Override + public boolean matches(ResolveInfoFlags argument) { + return argument.getValue() == flagsWanted; + } + + @Override + public String toString() { + return String.valueOf(flagsWanted); + } + }); + } } diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java index f75a72d635dd..21ab8fc97802 100644 --- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java +++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java @@ -41,7 +41,6 @@ import android.util.Log; import com.android.internal.os.ApplicationSharedMemory; import android.platform.test.annotations.DisabledOnRavenwood; -import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; diff --git a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java index 8b513cb996b5..524e35535f03 100644 --- a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java +++ b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java @@ -136,9 +136,11 @@ public class SystemFeaturesCacheTest { SystemFeaturesCache cache = new SystemFeaturesCache(features); SystemFeaturesCache.clearInstance(); + assertThat(SystemFeaturesCache.hasInstance()).isFalse(); assertThrows(IllegalStateException.class, () -> SystemFeaturesCache.getInstance()); SystemFeaturesCache.setInstance(cache); + assertThat(SystemFeaturesCache.hasInstance()).isTrue(); assertThat(SystemFeaturesCache.getInstance()).isEqualTo(cache); assertThrows( @@ -149,6 +151,7 @@ public class SystemFeaturesCacheTest { @Test public void testSingletonAutomaticallySetWithFeatureEnabled() { assumeTrue(android.content.pm.Flags.cacheSdkSystemFeatures()); + assertThat(SystemFeaturesCache.hasInstance()).isTrue(); assertThat(SystemFeaturesCache.getInstance()).isNotNull(); } diff --git a/core/tests/coretests/src/android/os/AidlTest.java b/core/tests/coretests/src/android/os/AidlTest.java index 006828f12156..570f236905c2 100644 --- a/core/tests/coretests/src/android/os/AidlTest.java +++ b/core/tests/coretests/src/android/os/AidlTest.java @@ -22,7 +22,7 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -35,7 +35,7 @@ import org.junit.Test; import java.util.List; -@IgnoreUnderRavenwood(blockedBy = Parcel.class) +@DisabledOnRavenwood(blockedBy = Parcel.class) public class AidlTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java b/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java index 5ef14604e2ca..3125fdd73a47 100644 --- a/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java +++ b/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java @@ -25,7 +25,7 @@ import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArraySet; import android.util.Log; @@ -55,7 +55,7 @@ import java.util.concurrent.atomic.AtomicReference; * Tests functionality of {@link android.os.IBinder.DeathRecipient} callbacks. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class BinderDeathRecipientTest { private static final String TAG = BinderDeathRecipientTest.class.getSimpleName(); private static final String TEST_PACKAGE_NAME_1 = diff --git a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java index 523fe1a8aa5d..0ebd2930a18d 100644 --- a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java +++ b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java @@ -27,7 +27,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -55,7 +55,7 @@ import java.util.concurrent.atomic.AtomicReference; * Tests functionality of {@link android.os.IBinder.FrozenStateChangeCallback}. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class BinderFrozenStateChangeNotificationTest { private static final String TAG = BinderFrozenStateChangeNotificationTest.class.getSimpleName(); diff --git a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java index 4dfe2e28218e..31353e73a6c0 100644 --- a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java +++ b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java @@ -24,7 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -74,7 +74,7 @@ import java.util.function.Consumer; */ @LargeTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class BinderProxyCountingTest { private static final String TAG = BinderProxyCountingTest.class.getSimpleName(); diff --git a/core/tests/coretests/src/android/os/BinderProxyTest.java b/core/tests/coretests/src/android/os/BinderProxyTest.java index 5fff0b8d0849..656d3bfcfe93 100644 --- a/core/tests/coretests/src/android/os/BinderProxyTest.java +++ b/core/tests/coretests/src/android/os/BinderProxyTest.java @@ -27,7 +27,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -43,7 +43,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class BinderProxyTest { private static class CountingListener implements Binder.ProxyTransactListener { int mStartedCount; diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java index 9a679d8e8a96..343802888325 100644 --- a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java +++ b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java @@ -24,7 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -46,7 +46,7 @@ import java.io.IOException; * Test whether Binder calls inherit thread priorities correctly. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class BinderThreadPriorityTest { private static final String TAG = "BinderThreadPriorityTest"; diff --git a/core/tests/coretests/src/android/os/BinderWorkSourceTest.java b/core/tests/coretests/src/android/os/BinderWorkSourceTest.java index 98e96c28d460..9b61cd2ff03d 100644 --- a/core/tests/coretests/src/android/os/BinderWorkSourceTest.java +++ b/core/tests/coretests/src/android/os/BinderWorkSourceTest.java @@ -24,7 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; @@ -45,7 +45,7 @@ import org.junit.runner.RunWith; @LargeTest @Presubmit @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class BinderWorkSourceTest { private static Context sContext; private static final int UID = 100; diff --git a/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java b/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java index 2117e7429a68..1e6fc15d6f20 100644 --- a/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java +++ b/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java @@ -22,7 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.CancellationSignalBeamer.Receiver; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.PollingCheck; import android.util.PollingCheck.PollingCheckCondition; @@ -44,7 +44,7 @@ import java.util.concurrent.CountDownLatch; @RunWith(AndroidJUnit4.class) @SmallTest -@IgnoreUnderRavenwood(blockedBy = CancellationSignalBeamer.class) +@DisabledOnRavenwood(blockedBy = CancellationSignalBeamer.class) public class CancellationSignalBeamerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/CancellationSignalTest.java b/core/tests/coretests/src/android/os/CancellationSignalTest.java index 8e11df5428f2..3b05cf7fbfa6 100644 --- a/core/tests/coretests/src/android/os/CancellationSignalTest.java +++ b/core/tests/coretests/src/android/os/CancellationSignalTest.java @@ -19,11 +19,8 @@ package android.os; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import android.platform.test.ravenwood.RavenwoodRule; - import androidx.test.ext.junit.runners.AndroidJUnit4; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,11 +29,6 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class CancellationSignalTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - @Test public void testSimple() throws Exception { final CancellationSignal signal = new CancellationSignal(); diff --git a/core/tests/coretests/src/android/os/EnvironmentTest.java b/core/tests/coretests/src/android/os/EnvironmentTest.java index 1b496243e48d..99ce175d0871 100644 --- a/core/tests/coretests/src/android/os/EnvironmentTest.java +++ b/core/tests/coretests/src/android/os/EnvironmentTest.java @@ -28,7 +28,7 @@ import static org.junit.Assert.assertEquals; import android.content.Context; import android.os.storage.StorageManager; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -46,7 +46,7 @@ import java.util.UUID; import java.util.function.BiFunction; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = Environment.class) +@DisabledOnRavenwood(blockedBy = Environment.class) public class EnvironmentTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/FileBridgeTest.java b/core/tests/coretests/src/android/os/FileBridgeTest.java index 726670b4d625..fa2a5f4d60a5 100644 --- a/core/tests/coretests/src/android/os/FileBridgeTest.java +++ b/core/tests/coretests/src/android/os/FileBridgeTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.FileBridge.FileBridgeOutputStream; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.test.MoreAsserts; @@ -46,7 +46,7 @@ import java.nio.charset.StandardCharsets; import java.util.Random; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ParcelFileDescriptor.class) +@DisabledOnRavenwood(blockedBy = ParcelFileDescriptor.class) public class FileBridgeTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/FileObserverTest.java b/core/tests/coretests/src/android/os/FileObserverTest.java index 3cd8045c32cb..6412023301b3 100644 --- a/core/tests/coretests/src/android/os/FileObserverTest.java +++ b/core/tests/coretests/src/android/os/FileObserverTest.java @@ -19,7 +19,7 @@ package android.os; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -42,7 +42,7 @@ import java.util.List; import java.util.Map; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = FileObserver.class) +@DisabledOnRavenwood(blockedBy = FileObserver.class) public class FileObserverTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java index 791ec5d0cea3..2b49b38607d8 100644 --- a/core/tests/coretests/src/android/os/IpcDataCacheTest.java +++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java @@ -26,7 +26,7 @@ import static org.junit.Assert.fail; import android.app.PropertyInvalidatedCache; import android.app.PropertyInvalidatedCache.Args; import android.multiuser.Flags; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; diff --git a/core/tests/coretests/src/android/os/MemoryFileTest.java b/core/tests/coretests/src/android/os/MemoryFileTest.java index a69542479afc..38ba6396d3b8 100644 --- a/core/tests/coretests/src/android/os/MemoryFileTest.java +++ b/core/tests/coretests/src/android/os/MemoryFileTest.java @@ -19,7 +19,7 @@ package android.os; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -40,7 +40,7 @@ import java.util.Arrays; import java.util.List; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = MemoryFile.class) +@DisabledOnRavenwood(blockedBy = MemoryFile.class) public class MemoryFileTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/MessengerTest.java b/core/tests/coretests/src/android/os/MessengerTest.java index eb6263fe8053..2014aa795828 100644 --- a/core/tests/coretests/src/android/os/MessengerTest.java +++ b/core/tests/coretests/src/android/os/MessengerTest.java @@ -21,7 +21,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -35,7 +35,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) +@DisabledOnRavenwood(blockedBy = ActivityManager.class) public class MessengerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/ParcelTest.java b/core/tests/coretests/src/android/os/ParcelTest.java index 3e6520106ab0..bb059108d4b6 100644 --- a/core/tests/coretests/src/android/os/ParcelTest.java +++ b/core/tests/coretests/src/android/os/ParcelTest.java @@ -29,6 +29,8 @@ import android.util.Log; import androidx.test.ext.junit.runners.AndroidJUnit4; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -416,4 +418,63 @@ public class ParcelTest { int binderEndPos = pA.dataPosition(); assertTrue(pA.hasBinders(binderStartPos, binderEndPos - binderStartPos)); } + + private static final byte[] TEST_DATA = new byte[] {4, 8, 15, 16, 23, 42}; + + // Allow for some Parcel overhead + private static final int TEST_DATA_LENGTH = TEST_DATA.length + 100; + + @Test + public void testMarshall_ByteBuffer_wrapped() { + ByteBuffer bb = ByteBuffer.allocate(TEST_DATA_LENGTH); + testMarshall_ByteBuffer(bb); + } + + @Test + public void testMarshall_DirectByteBuffer() { + ByteBuffer bb = ByteBuffer.allocateDirect(TEST_DATA_LENGTH); + testMarshall_ByteBuffer(bb); + } + + private void testMarshall_ByteBuffer(ByteBuffer bb) { + // Ensure that Parcel respects the starting offset by not starting at 0 + bb.position(1); + bb.mark(); + + // Parcel test data, then marshall into the ByteBuffer + Parcel p1 = Parcel.obtain(); + p1.writeByteArray(TEST_DATA); + p1.marshall(bb); + p1.recycle(); + + assertTrue(bb.position() > 1); + bb.reset(); + + // Unmarshall test data into a new Parcel + Parcel p2 = Parcel.obtain(); + bb.reset(); + p2.unmarshall(bb); + assertTrue(bb.position() > 1); + p2.setDataPosition(0); + byte[] marshalled = p2.marshall(); + + bb.reset(); + for (int i = 0; i < TEST_DATA.length; i++) { + assertEquals(bb.get(), marshalled[i]); + } + + byte[] testDataCopy = new byte[TEST_DATA.length]; + p2.setDataPosition(0); + p2.readByteArray(testDataCopy); + for (int i = 0; i < TEST_DATA.length; i++) { + assertEquals(TEST_DATA[i], testDataCopy[i]); + } + + // Test that overflowing the buffer throws an exception + bb.reset(); + // Leave certainly not enough room for the test data + bb.limit(bb.position() + TEST_DATA.length - 1); + assertThrows(BufferOverflowException.class, () -> p2.marshall(bb)); + p2.recycle(); + } } diff --git a/core/tests/coretests/src/android/os/PerfettoTraceTest.java b/core/tests/coretests/src/android/os/PerfettoTraceTest.java index 790ac4a55dc6..b345315eb8eb 100644 --- a/core/tests/coretests/src/android/os/PerfettoTraceTest.java +++ b/core/tests/coretests/src/android/os/PerfettoTraceTest.java @@ -23,7 +23,7 @@ import static com.google.common.truth.Truth.assertThat; import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH; import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; @@ -68,7 +68,7 @@ import java.util.concurrent.TimeUnit; * while tracing on the emulator and then run traceview to view the trace. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = PerfettoTrace.class) +@DisabledOnRavenwood(blockedBy = PerfettoTrace.class) public class PerfettoTraceTest { @Rule public final CheckFlagsRule mCheckFlagsRule = diff --git a/core/tests/coretests/src/android/os/PerformanceCollectorTest.java b/core/tests/coretests/src/android/os/PerformanceCollectorTest.java index 436720ee1338..c2566804c1f0 100644 --- a/core/tests/coretests/src/android/os/PerformanceCollectorTest.java +++ b/core/tests/coretests/src/android/os/PerformanceCollectorTest.java @@ -22,7 +22,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.os.PerformanceCollector.PerformanceResultsWriter; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -40,7 +40,7 @@ import java.util.ArrayList; import java.util.Random; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = PerformanceCollector.class) +@DisabledOnRavenwood(blockedBy = PerformanceCollector.class) public class PerformanceCollectorTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java index 4b49fde5e61a..b7c25f2246d9 100644 --- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeNotNull; import android.os.PerformanceHintManager.Session; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -38,7 +38,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = PerformanceHintManager.class) +@DisabledOnRavenwood(blockedBy = PerformanceHintManager.class) public class PerformanceHintManagerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/ProcessTest.java b/core/tests/coretests/src/android/os/ProcessTest.java index ea39db7b0057..3d50cfe2fdfb 100644 --- a/core/tests/coretests/src/android/os/ProcessTest.java +++ b/core/tests/coretests/src/android/os/ProcessTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import org.junit.Rule; @@ -29,7 +29,7 @@ import org.junit.Test; import java.util.Arrays; -@IgnoreUnderRavenwood(blockedBy = Process.class) +@DisabledOnRavenwood(blockedBy = Process.class) public class ProcessTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java index e22c862764cd..a6160bb5b285 100644 --- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java +++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import android.content.Context; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.system.Os; @@ -44,7 +44,7 @@ import java.io.FileOutputStream; import java.util.Arrays; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = RedactingFileDescriptor.class) +@DisabledOnRavenwood(blockedBy = RedactingFileDescriptor.class) public class RedactingFileDescriptorTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/RemoteCallbackTest.java b/core/tests/coretests/src/android/os/RemoteCallbackTest.java index ddcc380230a9..cbbaa75466be 100644 --- a/core/tests/coretests/src/android/os/RemoteCallbackTest.java +++ b/core/tests/coretests/src/android/os/RemoteCallbackTest.java @@ -19,11 +19,8 @@ package android.os; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.platform.test.ravenwood.RavenwoodRule; - import androidx.test.ext.junit.runners.AndroidJUnit4; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,11 +29,6 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class RemoteCallbackTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - @Test public void testSimple() throws Exception { final CountDownLatch latch = new CountDownLatch(1); diff --git a/core/tests/coretests/src/android/os/ResultReceiverTest.java b/core/tests/coretests/src/android/os/ResultReceiverTest.java index be67825ae4d2..21d40781ea52 100644 --- a/core/tests/coretests/src/android/os/ResultReceiverTest.java +++ b/core/tests/coretests/src/android/os/ResultReceiverTest.java @@ -19,11 +19,8 @@ package android.os; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.platform.test.ravenwood.RavenwoodRule; - import androidx.test.ext.junit.runners.AndroidJUnit4; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,11 +29,6 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class ResultReceiverTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - @Test public void testSimple() throws Exception { final CountDownLatch latch = new CountDownLatch(1); diff --git a/core/tests/coretests/src/android/os/TraceTest.java b/core/tests/coretests/src/android/os/TraceTest.java index 5462f3257189..4117dd68d794 100644 --- a/core/tests/coretests/src/android/os/TraceTest.java +++ b/core/tests/coretests/src/android/os/TraceTest.java @@ -16,7 +16,7 @@ package android.os; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -105,7 +105,7 @@ public class TraceTest { @Test @SmallTest - @IgnoreUnderRavenwood(blockedBy = Debug.class) + @DisabledOnRavenwood(blockedBy = Debug.class) public void testNativeTracingFromJava() { long start = System.currentTimeMillis(); @@ -126,7 +126,7 @@ public class TraceTest { // This should not run in the automated suite. @Suppress - @IgnoreUnderRavenwood(blockedBy = Debug.class) + @DisabledOnRavenwood(blockedBy = Debug.class) public void disableTestNativeTracingFromC() { long start = System.currentTimeMillis(); @@ -142,7 +142,7 @@ public class TraceTest { @Test @LargeTest @Suppress // Failing. - @IgnoreUnderRavenwood(blockedBy = Debug.class) + @DisabledOnRavenwood(blockedBy = Debug.class) public void testMethodTracing() { long start = System.currentTimeMillis(); diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java index f81b31d0bd5a..1b7bb4107bcf 100644 --- a/core/tests/coretests/src/android/os/VintfObjectTest.java +++ b/core/tests/coretests/src/android/os/VintfObjectTest.java @@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static java.util.stream.Collectors.toList; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Pair; @@ -37,7 +37,7 @@ import java.util.stream.Stream; import javax.xml.parsers.DocumentBuilderFactory; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = VintfObject.class) +@DisabledOnRavenwood(blockedBy = VintfObject.class) public class VintfObjectTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/os/WorkSourceParcelTest.java b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java index 5f49186df0f5..0ebf128cafef 100644 --- a/core/tests/coretests/src/android/os/WorkSourceParcelTest.java +++ b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java @@ -18,7 +18,7 @@ package android.os; import static org.junit.Assert.assertEquals; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -30,7 +30,7 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest -@IgnoreUnderRavenwood(reason = "JNI") +@DisabledOnRavenwood(reason = "JNI") public class WorkSourceParcelTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); @@ -49,7 +49,7 @@ public class WorkSourceParcelTest { String[] names, int parcelEndMarker); static { - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { System.loadLibrary("worksourceparceltest_jni"); } } diff --git a/core/tests/coretests/src/android/util/ArrayMapTest.java b/core/tests/coretests/src/android/util/ArrayMapTest.java index c7efe6f93f0d..d71a60323311 100644 --- a/core/tests/coretests/src/android/util/ArrayMapTest.java +++ b/core/tests/coretests/src/android/util/ArrayMapTest.java @@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; @@ -57,7 +57,7 @@ public class ArrayMapTest { */ @Test @Ignore("Failing; b/399137661") - @IgnoreUnderRavenwood(reason = "Long test runtime") + @DisabledOnRavenwood(reason = "Long test runtime") public void testConcurrentModificationException() throws Exception { final int TEST_LEN_MS = 5000; System.out.println("Starting ArrayMap concurrency test"); diff --git a/core/tests/coretests/src/android/util/CharsetUtilsTest.java b/core/tests/coretests/src/android/util/CharsetUtilsTest.java index 33936e9147bc..cf6e1ebf1bdc 100644 --- a/core/tests/coretests/src/android/util/CharsetUtilsTest.java +++ b/core/tests/coretests/src/android/util/CharsetUtilsTest.java @@ -18,7 +18,7 @@ package android.util; import static org.junit.Assert.assertEquals; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -33,7 +33,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = CharsetUtils.class) +@DisabledOnRavenwood(blockedBy = CharsetUtils.class) public class CharsetUtilsTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); @@ -43,7 +43,7 @@ public class CharsetUtilsTest { @Before public void setUp() { - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 8); destPtr = VMRuntime.getRuntime().addressOf(dest); } diff --git a/core/tests/coretests/src/android/util/CloseGuardTest.java b/core/tests/coretests/src/android/util/CloseGuardTest.java index 15c57b1aa6f7..c91ef1c751c4 100644 --- a/core/tests/coretests/src/android/util/CloseGuardTest.java +++ b/core/tests/coretests/src/android/util/CloseGuardTest.java @@ -16,7 +16,7 @@ package android.util; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import libcore.dalvik.system.CloseGuardSupport; @@ -26,7 +26,7 @@ import org.junit.Test; import org.junit.rules.TestRule; /** Unit tests for {@link android.util.CloseGuard} */ -@IgnoreUnderRavenwood(blockedBy = CloseGuard.class) +@DisabledOnRavenwood(blockedBy = CloseGuard.class) public class CloseGuardTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); @@ -35,7 +35,7 @@ public class CloseGuardTest { public final TestRule rule; public CloseGuardTest() { - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { rule = CloseGuardSupport.getRule(); } else { rule = null; diff --git a/core/tests/coretests/src/android/util/HashedStringCacheTest.java b/core/tests/coretests/src/android/util/HashedStringCacheTest.java index 08c85ac5c0d6..c26855bc63a1 100644 --- a/core/tests/coretests/src/android/util/HashedStringCacheTest.java +++ b/core/tests/coretests/src/android/util/HashedStringCacheTest.java @@ -26,7 +26,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Environment; import android.os.storage.StorageManager; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -40,7 +40,7 @@ import java.io.File; /** * Unit tests for {@link HashedStringCache}. */ -@IgnoreUnderRavenwood(blockedBy = HashedStringCache.class) +@DisabledOnRavenwood(blockedBy = HashedStringCache.class) public class HashedStringCacheTest { private static final String TAG = "HashedStringCacheTest"; private Context mContext; @@ -51,7 +51,7 @@ public class HashedStringCacheTest { @Before public void setup() { - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { mContext = InstrumentationRegistry.getContext(); clearSharedPreferences(); } else { diff --git a/core/tests/coretests/src/android/util/LogNullabilityTest.java b/core/tests/coretests/src/android/util/LogNullabilityTest.java index 5aa2626b6de7..795444d55432 100644 --- a/core/tests/coretests/src/android/util/LogNullabilityTest.java +++ b/core/tests/coretests/src/android/util/LogNullabilityTest.java @@ -37,7 +37,7 @@ public final class LogNullabilityTest { Log.i(null, ""); Log.w(null, ""); Log.e(null, ""); - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { Log.wtf(null, ""); Log.wtfStack(null, ""); } @@ -53,7 +53,7 @@ public final class LogNullabilityTest { Log.i(null, "", new Throwable()); Log.w(null, "", new Throwable()); Log.e(null, "", new Throwable()); - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { Log.wtf(null, "", new Throwable()); } Log.printlns(Log.LOG_ID_MAIN, Log.INFO, null, "", new Throwable()); @@ -90,7 +90,7 @@ public final class LogNullabilityTest { } catch (NullPointerException expected) { } - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { Log.wtf("", (String) null); Log.wtfStack("", (String) null); } @@ -111,7 +111,7 @@ public final class LogNullabilityTest { Log.i("", null, new Throwable()); Log.w("", null, new Throwable()); Log.e("", null, new Throwable()); - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { Log.wtf("", null, new Throwable()); } Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, new Throwable()); @@ -124,7 +124,7 @@ public final class LogNullabilityTest { Log.i("", "", null); Log.w("", "", null); Log.e("", "", null); - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { Log.wtf("", "", null); } @@ -136,7 +136,7 @@ public final class LogNullabilityTest { // Implicit assertions of not crashing. // WTF has its own (String, Throwable) overload with different behavior. - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { try { Log.wtf("", (Throwable) null); fail(); @@ -152,7 +152,7 @@ public final class LogNullabilityTest { Log.i("", null, null); Log.w("", null, null); Log.e("", null, null); - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { Log.wtf("", null, null); } Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, null); diff --git a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java index ce1eabc741a3..32fb3a27459c 100644 --- a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java +++ b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java @@ -31,7 +31,7 @@ import static java.lang.String.join; import static java.util.Arrays.asList; import android.net.Network; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -56,7 +56,7 @@ import java.util.stream.Stream; @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = NtpTrustedTime.class) +@DisabledOnRavenwood(blockedBy = NtpTrustedTime.class) public class NtpTrustedTimeTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java index 48e76f79a928..56d6594a488a 100644 --- a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java +++ b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java @@ -26,7 +26,7 @@ import static org.junit.Assert.assertTrue; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import android.content.Context; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.core.app.ApplicationProvider; @@ -52,7 +52,7 @@ import java.util.zip.ZipFile; /** Unit test for {@link android.util.apk.SourceStampVerifier} */ @RunWith(JUnit4.class) -@IgnoreUnderRavenwood(blockedBy = SourceStampVerifier.class) +@DisabledOnRavenwood(blockedBy = SourceStampVerifier.class) public class SourceStampVerifierTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index af87af0d243f..79d8bb169a1f 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -1208,8 +1208,9 @@ public class InsetsControllerTest { }); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - verify(mTestHost, times(1)).updateAnimatingTypes(eq(types)); - verify(mTestHost, times(1)).updateAnimatingTypes(eq(0) /* animatingTypes */); + verify(mTestHost, times(1)).updateAnimatingTypes(eq(types), any() /* statsToken */); + verify(mTestHost, times(1)).updateAnimatingTypes(eq(0) /* animatingTypes */, + any() /* statsToken */); } private void waitUntilNextFrame() throws Exception { diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 39f3d3319ad3..5774109e1451 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -1063,7 +1063,7 @@ public class ViewRootImplTest { ViewRootImpl viewRootImpl = mView.getViewRootImpl(); sInstrumentation.runOnMainSync(() -> { mView.invalidate(); - viewRootImpl.updateAnimatingTypes(Type.systemBars()); + viewRootImpl.updateAnimatingTypes(Type.systemBars(), null /* statsToken */); mView.invalidate(); }); sInstrumentation.waitForIdleSync(); diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java index 9110898e18c9..2dcb692918d1 100644 --- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java +++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java @@ -1080,6 +1080,9 @@ public class RemoteViewsTest { rv.setOnClickFillInIntent(R.id.view, fillInIntent); assertNotEquals(0, fillInIntent.getExtendedFlags() & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED); + + RemoteViews.RemoteResponse rr = RemoteViews.RemoteResponse.fromFillInIntent(null); + assertNotNull(rr); } private static LayoutInflater.Factory2 createLayoutInflaterFactory(String viewTypeToReplace, diff --git a/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java b/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java index 8bdf4c6192ba..402ba0d9f05e 100644 --- a/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java @@ -21,19 +21,13 @@ import static com.google.common.truth.Truth.assertThat; import android.os.ConditionVariable; import android.os.Handler; import android.os.Looper; -import android.platform.test.ravenwood.RavenwoodRule; -import org.junit.Rule; import org.junit.Test; import java.util.concurrent.Executor; public class BackgroundThreadTest { - @Rule - public final RavenwoodRule mRavenwood = - new RavenwoodRule.Builder().setProvideMainThread(true).build(); - @Test public void test_get() { BackgroundThread thread = BackgroundThread.get(); diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java index 5f8ab283c789..f44aa050619a 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java @@ -29,7 +29,7 @@ import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.SystemClock; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArrayMap; @@ -59,7 +59,7 @@ import java.util.Set; @SmallTest @RunWith(AndroidJUnit4.class) @Presubmit -@IgnoreUnderRavenwood(blockedBy = BinderCallsStats.class) +@DisabledOnRavenwood(blockedBy = BinderCallsStats.class) public class BinderCallsStatsTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java index 3355cc34ee1c..5c2bf3873679 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java @@ -23,7 +23,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import android.os.Binder; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArrayMap; @@ -50,7 +50,7 @@ import java.util.Random; @SmallTest @RunWith(AndroidJUnit4.class) @Presubmit -@IgnoreUnderRavenwood(blockedBy = BinderLatencyObserver.class) +@DisabledOnRavenwood(blockedBy = BinderLatencyObserver.class) public class BinderLatencyObserverTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/DebugTest.java b/core/tests/coretests/src/com/android/internal/os/DebugTest.java index 4371f2699d4f..e6a0e4a01919 100644 --- a/core/tests/coretests/src/com/android/internal/os/DebugTest.java +++ b/core/tests/coretests/src/com/android/internal/os/DebugTest.java @@ -19,7 +19,7 @@ package com.android.internal.os; import static org.junit.Assert.assertTrue; import android.os.Debug; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -28,7 +28,7 @@ import org.junit.Rule; import org.junit.Test; @SmallTest -@IgnoreUnderRavenwood(reason = "Requires ART support") +@DisabledOnRavenwood(reason = "Requires ART support") public class DebugTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java index 8fd87c01f584..a625317e4424 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.os.FileUtils; import android.os.SystemClock; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.InstrumentationRegistry; @@ -60,7 +60,7 @@ import java.util.stream.IntStream; */ @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuProcStringReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java index 78cf65cd466d..06d75211ddf2 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java @@ -24,7 +24,7 @@ import static org.testng.Assert.assertThrows; import static java.util.stream.Collectors.toList; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; @@ -47,7 +47,7 @@ import java.util.Collections; @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuThreadReaderDiffTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java index 8c5e3d0e0724..bb7a81a81d28 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java @@ -22,7 +22,7 @@ import static org.junit.Assert.assertTrue; import android.os.Process; import android.os.SystemClock; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -50,7 +50,7 @@ import java.util.stream.Collectors; */ @RunWith(AndroidJUnit4.class) @LargeTest -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuThreadReaderEndToEndTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java index c3d4b839b15e..74dd99987d2e 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java @@ -25,7 +25,7 @@ import static org.testng.Assert.assertThrows; import android.content.Context; import android.os.FileUtils; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; @@ -51,7 +51,7 @@ import java.util.function.Predicate; @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuThreadReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java index d35e0fc95aa1..fc090caccae8 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.os.FileUtils; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; import android.util.SparseLongArray; @@ -54,7 +54,7 @@ import java.util.Random; */ @SmallTest @RunWith(Parameterized.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuUidActiveTimeReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java index b75ad7f169cd..5a01175ffedc 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.content.Context; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; @@ -52,7 +52,7 @@ import java.util.concurrent.TimeUnit; @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuUidBpfMapReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java index 8807de089864..bde66c7ba1cf 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.os.FileUtils; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; @@ -55,7 +55,7 @@ import java.util.Random; */ @SmallTest @RunWith(Parameterized.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuUidClusterTimeReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java index b73034437350..28c340d0122e 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java @@ -24,7 +24,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.os.FileUtils; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; @@ -58,7 +58,7 @@ import java.util.Random; */ @SmallTest @RunWith(Parameterized.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuUidFreqTimeReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java index 864e1985d2e6..010d3d6ddafa 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.os.FileUtils; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; @@ -52,7 +52,7 @@ import java.util.Random; */ @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelCpuUidUserSysTimeReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java b/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java index a74f339b4f07..2b99a27dcbae 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java @@ -18,7 +18,7 @@ package com.android.internal.os; import static org.junit.Assert.assertEquals; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.LongSparseLongArray; @@ -36,7 +36,7 @@ import java.io.BufferedReader; * Tests for KernelMemoryBandwidthStats parsing and delta calculation, based on memory_state_time. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelMemoryBandwidthStatsTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java index cdfef251e217..a4b44c70ef81 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java @@ -19,7 +19,7 @@ package com.android.internal.os; import static com.google.common.truth.Truth.assertThat; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -35,7 +35,7 @@ import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelSingleProcessCpuThreadReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java index 0ba2d851feb9..262d6a2d6fa7 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.annotation.SuppressLint; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; @@ -47,7 +47,7 @@ import java.util.Collection; @SmallTest @RunWith(Parameterized.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class KernelSingleUidTimeReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java b/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java index 93dd09db8552..0de5f158c2d4 100644 --- a/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import android.os.FileUtils; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -40,7 +40,7 @@ import java.nio.file.Path; @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ProcTimeInStateReader.class) +@DisabledOnRavenwood(blockedBy = ProcTimeInStateReader.class) public class ProcTimeInStateReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java b/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java index d11c500b055a..46cb382c30d5 100644 --- a/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java @@ -18,7 +18,7 @@ package com.android.internal.os; import static com.google.common.truth.Truth.assertThat; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -30,7 +30,7 @@ import org.junit.runners.JUnit4; @SmallTest @RunWith(JUnit4.class) -@IgnoreUnderRavenwood(reason = "Needs kernel support") +@DisabledOnRavenwood(reason = "Needs kernel support") public class ProcessCpuTrackerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java index d1c066821cff..dad1f136b70c 100644 --- a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java +++ b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java @@ -32,7 +32,7 @@ public class RavenwoodEnvironmentTest { @Test public void testIsRunningOnRavenwood() { - assertEquals(RavenwoodRule.isUnderRavenwood(), + assertEquals(RavenwoodRule.isOnRavenwood(), RavenwoodEnvironment.getInstance().isRunningOnRavenwood()); } } diff --git a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java index aa59afe6dd7a..28533de4dbab 100644 --- a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java +++ b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java @@ -23,7 +23,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.text.Spannable; import android.text.SpannableString; @@ -43,7 +43,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = Color.class) +@DisabledOnRavenwood(blockedBy = Color.class) public class ContrastColorUtilTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java index aee352bc3a79..83eb1e64d706 100644 --- a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java @@ -24,7 +24,7 @@ import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERAC import static com.google.common.truth.Truth.assertThat; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DeviceConfig; @@ -45,7 +45,7 @@ import java.util.List; * {@link LatencyTrackerTest} */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = DeviceConfig.class) +@DisabledOnRavenwood(blockedBy = DeviceConfig.class) public class FakeLatencyTrackerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java index 316b95ac1b7d..f603fdb6507c 100644 --- a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java +++ b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java @@ -64,7 +64,7 @@ public class FastDataTest { @Parameters(name = "use4ByteSequence={0}") public static Collection<Object[]> data() { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { // TODO: 4-byte sequences are only supported on ART return Arrays.asList(new Object[][]{{false}}); } else { diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java index ce265a3178d3..141565139734 100644 --- a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java @@ -25,7 +25,7 @@ import static com.android.internal.util.LatencyTracker.STATSD_ACTION; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DeviceConfig; @@ -51,7 +51,7 @@ import java.util.Map; import java.util.stream.Collectors; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = DeviceConfig.class) +@DisabledOnRavenwood(blockedBy = DeviceConfig.class) public class LatencyTrackerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java index e0d5499835a8..bb1c9edf9b58 100644 --- a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java +++ b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java @@ -18,7 +18,7 @@ package com.android.internal.util; import static org.junit.Assert.assertEquals; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -29,7 +29,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ProgressReporter.class) +@DisabledOnRavenwood(blockedBy = ProgressReporter.class) public class ProgressReporterTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java index d1fbc77cbd46..e0e24e7cabab 100644 --- a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java +++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java @@ -53,7 +53,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.ravenwood.RavenwoodRule; import android.provider.Settings; @@ -80,7 +80,7 @@ import java.util.concurrent.CompletableFuture; @RunWith(AndroidJUnit4.class) @SmallTest -@IgnoreUnderRavenwood(blockedBy = LockPatternUtils.class) +@DisabledOnRavenwood(blockedBy = LockPatternUtils.class) public class LockPatternUtilsTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/android/util/AtomicFileTest.java b/core/tests/utiltests/src/android/util/AtomicFileTest.java index 742307ba8c70..8897f0f05820 100644 --- a/core/tests/utiltests/src/android/util/AtomicFileTest.java +++ b/core/tests/utiltests/src/android/util/AtomicFileTest.java @@ -24,7 +24,7 @@ import static org.mockito.ArgumentMatchers.longThat; import static org.mockito.Mockito.spy; import android.os.SystemClock; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.annotation.NonNull; @@ -281,7 +281,7 @@ public class AtomicFileTest { } @Test - @IgnoreUnderRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class) + @DisabledOnRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class) public void testTimeLogging() throws Exception { var logger = spy(new SystemConfigFileCommitEventLogger("name")); var file = new AtomicFile(mBaseFile, logger); diff --git a/core/tests/utiltests/src/android/util/EventLogTest.java b/core/tests/utiltests/src/android/util/EventLogTest.java index 0ebf2c163d19..35803e7f698e 100644 --- a/core/tests/utiltests/src/android/util/EventLogTest.java +++ b/core/tests/utiltests/src/android/util/EventLogTest.java @@ -19,7 +19,7 @@ package android.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.EventLog.Event; @@ -51,7 +51,7 @@ public class EventLogTest { } @Test - @IgnoreUnderRavenwood(reason = "Reading not yet supported") + @DisabledOnRavenwood(reason = "Reading not yet supported") public void testWithNewData() throws Throwable { Event event = createEvent(() -> { EventLog.writeEvent(314, 123); diff --git a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java index 8093af9bb004..1459212d206e 100644 --- a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java +++ b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Parcel; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -39,13 +39,13 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = MemoryIntArray.class) +@DisabledOnRavenwood(blockedBy = MemoryIntArray.class) public class MemoryIntArrayTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); static { - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { System.loadLibrary("cutils"); System.loadLibrary("memoryintarraytest"); } diff --git a/core/tests/utiltests/src/android/util/MetadataReaderTest.java b/core/tests/utiltests/src/android/util/MetadataReaderTest.java index 14feed8b89a1..59815060f09b 100644 --- a/core/tests/utiltests/src/android/util/MetadataReaderTest.java +++ b/core/tests/utiltests/src/android/util/MetadataReaderTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertEquals; import android.media.ExifInterface; import android.os.Bundle; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DocumentsContract; import android.provider.MetadataReader; @@ -41,7 +41,7 @@ import java.io.IOException; import java.io.InputStream; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = MetadataReader.class) +@DisabledOnRavenwood(blockedBy = MetadataReader.class) public class MetadataReaderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java b/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java index 3bb79ec91d09..d64de68aee74 100644 --- a/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java +++ b/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java @@ -21,7 +21,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import android.os.SystemClock; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -32,7 +32,7 @@ import org.junit.runner.RunWith; import org.mockito.Mockito; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class) +@DisabledOnRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class) public class SystemConfigFileCommitEventLoggerTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java index 988854038e53..b86c815bb6ac 100644 --- a/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java @@ -21,7 +21,7 @@ import static com.android.internal.util.CharSequences.forAsciiBytes; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -32,7 +32,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = CharSequences.class) +@DisabledOnRavenwood(blockedBy = CharSequences.class) public class CharSequencesTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java index f91172df4f74..259d3945caf8 100644 --- a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.provider.DeviceConfig; import android.util.Log; @@ -145,7 +145,7 @@ public class FastXmlSerializerTest { @Test @LargeTest - @IgnoreUnderRavenwood(reason = "Long test runtime") + @DisabledOnRavenwood(reason = "Long test runtime") public void testAllCharacters() throws Exception { boolean ok = true; for (int i = 0; i < 0xffff; i++) { diff --git a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java index 7203b8c6a8c8..1af58a344332 100644 --- a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java @@ -25,7 +25,7 @@ import static org.junit.Assert.assertTrue; import android.graphics.Color; import android.os.Binder; import android.os.Bundle; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -39,7 +39,7 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest -@IgnoreUnderRavenwood(blockedBy = InlinePresentationStyleUtils.class) +@DisabledOnRavenwood(blockedBy = InlinePresentationStyleUtils.class) public class InlinePresentationStyleUtilsTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java index 6c3479722526..7e523bb12477 100644 --- a/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java @@ -18,7 +18,7 @@ package com.android.internal.util; import static org.junit.Assert.assertEquals; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -31,7 +31,7 @@ import org.junit.runner.RunWith; * Tests for {@link MimeIconUtils}. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = MimeIconUtils.class) +@DisabledOnRavenwood(blockedBy = MimeIconUtils.class) public class MimeIconUtilsTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java b/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java index c852e9f17bc0..dc353a5f5add 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java @@ -29,7 +29,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; @@ -52,7 +52,7 @@ import java.util.concurrent.Executor; @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ObservableServiceConnection.class) +@DisabledOnRavenwood(blockedBy = ObservableServiceConnection.class) public class ObservableServiceConnectionTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java b/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java index 096f303247ff..a881873f4075 100644 --- a/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java @@ -30,7 +30,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -52,7 +52,7 @@ import java.util.Queue; import java.util.concurrent.Executor; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = PersistentServiceConnection.class) +@DisabledOnRavenwood(blockedBy = PersistentServiceConnection.class) public class PersistentServiceConnectionTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java index b0db8a1da3a8..c7e0bbd149f5 100644 --- a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java @@ -24,8 +24,7 @@ import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.platform.test.annotations.IgnoreUnderRavenwood; -import android.platform.test.ravenwood.RavenwoodRule; +import android.platform.test.annotations.DisabledOnRavenwood; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -47,7 +46,7 @@ import org.mockito.stubbing.Answer; */ @SmallTest @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = WakeupMessage.class) +@DisabledOnRavenwood(blockedBy = WakeupMessage.class) public class WakeupMessageTest { private static final String TEST_CMD_NAME = "TEST cmd Name"; private static final int TEST_CMD = 18; @@ -55,11 +54,6 @@ public class WakeupMessageTest { private static final int TEST_ARG2 = 182; private static final Object TEST_OBJ = "hello"; - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - @Mock Context mContext; @Mock AlarmManager mAlarmManager; WakeupMessage mMessage; diff --git a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java index 502d6b6d7270..abedc4d91707 100644 --- a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import android.content.ContentProvider; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.provider.Settings; import android.test.mock.MockContentResolver; @@ -37,7 +37,7 @@ import org.junit.runner.RunWith; * Unit tests for FakeSettingsProvider. */ @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = ContentProvider.class) +@DisabledOnRavenwood(blockedBy = ContentProvider.class) public class FakeSettingsProviderTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule(); diff --git a/data/etc/preinstalled-packages-platform.xml b/data/etc/preinstalled-packages-platform.xml index 3b4014867ef7..f25ceb14fb10 100644 --- a/data/etc/preinstalled-packages-platform.xml +++ b/data/etc/preinstalled-packages-platform.xml @@ -139,4 +139,10 @@ to pre-existing users, but cannot uninstall pre-existing system packages from pr <install-in-user-type package="com.android.multiuser"> <install-in user-type="FULL" /> </install-in-user-type> + + <!-- PrivateSpace App, only install in private profile --> + <install-in-user-type package="com.android.privatespace"> + <install-in user-type="android.os.usertype.profile.PRIVATE" /> + </install-in-user-type> + </config> diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index cd5a54c2fd3f..a4ba2b398deb 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -755,6 +755,9 @@ public final class Bitmap implements Parcelable { if (b != null) { b.setPremultiplied(mRequestPremultiplied); b.mDensity = mDensity; + if (hasGainmap()) { + b.setGainmap(getGainmap().asShared()); + } } return b; } @@ -767,7 +770,8 @@ public final class Bitmap implements Parcelable { */ @NonNull public Bitmap asShared() { - if (nativeIsBackedByAshmem(mNativePtr) && nativeIsImmutable(mNativePtr)) { + if (nativeIsBackedByAshmem(mNativePtr) && nativeIsImmutable(mNativePtr) + && (!hasGainmap() || getGainmap().asShared() == getGainmap())) { return this; } Bitmap shared = createAshmemBitmap(); @@ -2091,7 +2095,7 @@ public final class Bitmap implements Parcelable { */ public void setGainmap(@Nullable Gainmap gainmap) { checkRecycled("Bitmap is recycled"); - mGainmap = null; + mGainmap = gainmap; nativeSetGainmap(mNativePtr, gainmap == null ? 0 : gainmap.mNativePtr); } diff --git a/graphics/java/android/graphics/Gainmap.java b/graphics/java/android/graphics/Gainmap.java index 7fc13db85659..2417a1270bc5 100644 --- a/graphics/java/android/graphics/Gainmap.java +++ b/graphics/java/android/graphics/Gainmap.java @@ -161,6 +161,18 @@ public final class Gainmap implements Parcelable { } /** + * @hide + */ + public Gainmap asShared() { + final Bitmap sharedContents = mGainmapContents.asShared(); + if (sharedContents == mGainmapContents) { + return this; + } else { + return new Gainmap(sharedContents, nCreateCopy(mNativePtr)); + } + } + + /** * @return Returns the image data of the gainmap represented as a Bitmap. This is represented * as a Bitmap for broad API compatibility, however certain aspects of the Bitmap are ignored * such as {@link Bitmap#getColorSpace()} or {@link Bitmap#getGainmap()} as they are not diff --git a/libs/WindowManager/Shell/res/drawable/bubble_ic_settings.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_settings.xml new file mode 100644 index 000000000000..52b9ac26b72f --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/bubble_ic_settings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="20dp" + android:height="20dp" + android:viewportWidth="960" + android:viewportHeight="960" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M433,880Q406,880 386.5,862Q367,844 363,818L354,752Q341,747 329.5,740Q318,733 307,725L245,751Q220,762 195,753Q170,744 156,721L109,639Q95,616 101,590Q107,564 128,547L181,507Q180,500 180,493.5Q180,487 180,480Q180,473 180,466.5Q180,460 181,453L128,413Q107,396 101,370Q95,344 109,321L156,239Q170,216 195,207Q220,198 245,209L307,235Q318,227 330,220Q342,213 354,208L363,142Q367,116 386.5,98Q406,80 433,80L527,80Q554,80 573.5,98Q593,116 597,142L606,208Q619,213 630.5,220Q642,227 653,235L715,209Q740,198 765,207Q790,216 804,239L851,321Q865,344 859,370Q853,396 832,413L779,453Q780,460 780,466.5Q780,473 780,480Q780,487 780,493.5Q780,500 778,507L831,547Q852,564 858,590Q864,616 850,639L802,721Q788,744 763,753Q738,762 713,751L653,725Q642,733 630,740Q618,747 606,752L597,818Q593,844 573.5,862Q554,880 527,880L433,880ZM482,620Q540,620 581,579Q622,538 622,480Q622,422 581,381Q540,340 482,340Q423,340 382.5,381Q342,422 342,480Q342,538 382.5,579Q423,620 482,620Z"/> +</vector> diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml index fc8b29912955..9bb51a87c08f 100644 --- a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml +++ b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml @@ -31,7 +31,7 @@ android:layout_height="@dimen/bubble_popup_icon_size" android:tint="@androidprv:color/materialColorOutline" android:contentDescription="@null" - android:src="@drawable/pip_ic_settings"/> + android:src="@drawable/bubble_ic_settings"/> <TextView android:layout_width="wrap_content" diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml index 4daaf9c6b57f..225303b2d942 100644 --- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml +++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml @@ -103,4 +103,35 @@ </LinearLayout> + <!-- Menu option to move a bubble to fullscreen; only visible if bubble anything is enabled. --> + <LinearLayout + android:id="@+id/bubble_manage_menu_fullscreen_container" + android:background="@drawable/bubble_manage_menu_row" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" + android:minHeight="@dimen/bubble_menu_item_height" + android:gravity="center_vertical" + android:paddingStart="@dimen/bubble_menu_padding" + android:paddingEnd="@dimen/bubble_menu_padding" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/bubble_manage_menu_fullscreen_icon" + android:layout_width="@dimen/bubble_menu_icon_size" + android:layout_height="@dimen/bubble_menu_icon_size" + android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen" + android:tint="@color/bubbles_icon_tint"/> + + <TextView + android:id="@+id/bubble_manage_menu_fullscreen_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:text="@string/bubble_fullscreen_text" + android:textColor="@androidprv:color/materialColorOnSurface" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault" /> + + </LinearLayout> + </LinearLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml index ed8b54397076..bfaa40771894 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml @@ -43,8 +43,7 @@ android:layout_height="@dimen/desktop_mode_handle_menu_icon_radius" android:layout_marginStart="10dp" android:layout_marginEnd="12dp" - android:contentDescription="@string/app_icon_text" - android:importantForAccessibility="no"/> + android:contentDescription="@string/app_icon_text" /> <com.android.wm.shell.windowdecor.MarqueedTextView android:id="@+id/application_name" @@ -142,7 +141,6 @@ android:contentDescription="@string/screenshot_text" android:text="@string/screenshot_text" android:src="@drawable/desktop_mode_ic_handle_menu_screenshot" - android:importantForAccessibility="no" style="@style/DesktopModeHandleMenuActionButton"/> <com.android.wm.shell.windowdecor.HandleMenuActionButton @@ -150,7 +148,6 @@ android:contentDescription="@string/new_window_text" android:text="@string/new_window_text" android:src="@drawable/desktop_mode_ic_handle_menu_new_window" - android:importantForAccessibility="no" style="@style/DesktopModeHandleMenuActionButton"/> <com.android.wm.shell.windowdecor.HandleMenuActionButton @@ -158,7 +155,6 @@ android:contentDescription="@string/manage_windows_text" android:text="@string/manage_windows_text" android:src="@drawable/desktop_mode_ic_handle_menu_manage_windows" - android:importantForAccessibility="no" style="@style/DesktopModeHandleMenuActionButton"/> <com.android.wm.shell.windowdecor.HandleMenuActionButton @@ -166,7 +162,6 @@ android:contentDescription="@string/change_aspect_ratio_text" android:text="@string/change_aspect_ratio_text" android:src="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio" - android:importantForAccessibility="no" style="@style/DesktopModeHandleMenuActionButton"/> </LinearLayout> @@ -186,7 +181,6 @@ android:text="@string/open_in_browser_text" android:src="@drawable/desktop_mode_ic_handle_menu_open_in_browser" style="@style/DesktopModeHandleMenuActionButton" - android:importantForAccessibility="no" android:layout_width="0dp" android:layout_weight="1"/> diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml index de38e6fc2330..35e7de0e7c1e 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml @@ -22,8 +22,7 @@ android:layout_height="match_parent" android:gravity="start|center_vertical" android:paddingHorizontal="16dp" - android:clickable="true" - android:focusable="true" + android:importantForAccessibility="yes" android:orientation="horizontal" android:background="?android:attr/selectableItemBackground"> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 8abb9dffec67..0802f83ab837 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -100,8 +100,7 @@ <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> <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string> - <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) --> - <skip /> + <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string> <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen anytime from the app menu"</string> <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string> <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string> @@ -122,8 +121,7 @@ <string name="handle_text" msgid="4419667835599523257">"App handle"</string> <string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string> - <!-- no translation found for desktop_text (9058641752519570266) --> - <skip /> + <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string> <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string> <string name="more_button_text" msgid="3655388105592893530">"More"</string> <string name="float_button_text" msgid="9221657008391364581">"Float"</string> @@ -136,8 +134,7 @@ <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string> <string name="close_text" msgid="4986518933445178928">"Close"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string> - <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) --> - <skip /> + <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string> <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string> <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string> <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 2a8c88ed3a40..e1bf6638a9b2 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -291,6 +291,9 @@ <!-- Corner radius for expanded view drop target --> <dimen name="bubble_bar_expanded_view_drop_target_corner">28dp</dimen> <dimen name="bubble_bar_expanded_view_drop_target_padding">24dp</dimen> + <dimen name="bubble_bar_expanded_view_drop_target_padding_top">60dp</dimen> + <dimen name="bubble_bar_expanded_view_drop_target_padding_bottom">24dp</dimen> + <dimen name="bubble_bar_expanded_view_drop_target_padding_horizontal">48dp</dimen> <!-- Width of the box around bottom center of the screen where drag only leads to dismiss --> <dimen name="bubble_bar_dismiss_zone_width">192dp</dimen> <!-- Height of the box around bottom center of the screen where drag only leads to dismiss --> diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml index 637b47ab3ace..5f1db83d7acb 100644 --- a/libs/WindowManager/Shell/res/values/styles.xml +++ b/libs/WindowManager/Shell/res/values/styles.xml @@ -45,6 +45,7 @@ <item name="android:layout_height">52dp</item> <item name="android:textColor">@androidprv:color/materialColorOnSurface</item> <item name="android:drawableTint">@androidprv:color/materialColorOnSurface</item> + <item name="android:importantForAccessibility">no</item> </style> <style name="DesktopModeHandleMenuActionButtonImage"> diff --git a/libs/WindowManager/Shell/shared/res/values/dimen.xml b/libs/WindowManager/Shell/shared/res/values/dimen.xml index f6a176fb3be8..3b504cf713f1 100644 --- a/libs/WindowManager/Shell/shared/res/values/dimen.xml +++ b/libs/WindowManager/Shell/shared/res/values/dimen.xml @@ -31,6 +31,7 @@ <dimen name="drag_zone_desktop_window_expanded_view_height">350dp</dimen> <dimen name="drag_zone_split_from_bubble_height">100dp</dimen> <dimen name="drag_zone_split_from_bubble_width">60dp</dimen> + <dimen name="drag_zone_h_split_from_app_width_fold">140dp</dimen> <dimen name="drag_zone_h_split_from_expanded_view_width">60dp</dimen> <dimen name="drag_zone_v_split_from_expanded_view_width">200dp</dimen> <dimen name="drag_zone_v_split_from_expanded_view_height_tablet">285dp</dimen> diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt index 9bf56b075112..f4efcca28003 100644 --- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt @@ -80,7 +80,7 @@ class TypefaceUtils { fontStyle: Int = Typeface.NORMAL, ) { if (!Flags.enableGsf()) return - textView?.typeface = Typeface.create(fontFamily.name, fontStyle) + textView?.typeface = Typeface.create(fontFamily.value, fontStyle) } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index 912de813cf59..81eff6f7399a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -1306,7 +1306,11 @@ public class BubbleController implements ConfigurationChangeListener, // TODO b/392893178: Merge the unfold and the task view transition so that we don't // have to post a delayed runnable to the looper to update the bounds if (mStackView.isExpanded()) { - mStackView.postDelayed(() -> mStackView.updateExpandedView(), 500); + mStackView.postDelayed(() -> { + if (mStackView != null) { + mStackView.updateExpandedView(); + } + } , 500); } } if (newConfig.fontScale != mFontScale) { @@ -2643,9 +2647,9 @@ public class BubbleController implements ConfigurationChangeListener, mBubbleData.setSelectedBubbleAndExpandStack(bubbleToSelect); } - private void moveBubbleToFullscreen(String key) { + private void moveDraggedBubbleToFullscreen(String key, Point dropLocation) { Bubble b = mBubbleData.getBubbleInStackWithKey(key); - mBubbleTransitions.startDraggedBubbleIconToFullscreen(b); + mBubbleTransitions.startDraggedBubbleIconToFullscreen(b, dropLocation); } private boolean isDeviceLocked() { @@ -2936,8 +2940,9 @@ public class BubbleController implements ConfigurationChangeListener, } @Override - public void moveBubbleToFullscreen(String key) { - mMainExecutor.execute(() -> mController.moveBubbleToFullscreen(key)); + public void moveDraggedBubbleToFullscreen(String key, Point dropLocation) { + mMainExecutor.execute( + () -> mController.moveDraggedBubbleToFullscreen(key, dropLocation)); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index 8ac9230c36c3..426c3ee5b853 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -468,9 +468,12 @@ public class BubbleExpandedView extends LinearLayout { public void onTaskCreated() { // The taskId is saved to use for removeTask, // preventing appearance in recent tasks. - mTaskId = ((BubbleTaskViewListener) mCurrentTaskViewListener) - .getTaskId(); - + BubbleTaskViewListener listener = mCurrentTaskViewListener != null + ? ((BubbleTaskViewListener) mCurrentTaskViewListener) + : null; + mTaskId = listener != null + ? listener.getTaskId() + : bubbleTaskView.getTaskId(); setContentVisibility(true); } @@ -606,6 +609,10 @@ public class BubbleExpandedView extends LinearLayout { updateManageButtonIfExists(); } + public float getCornerRadius() { + return mCornerRadius; + } + /** * Updates the size and visuals of the pointer if {@link #mPointerView} is initialized. * Does nothing otherwise. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java index 70340d7032b4..03d6b0a8075d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java @@ -103,7 +103,9 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider { private int mManageButtonHeight; private int mOverflowHeight; private int mMinimumFlyoutWidthLargeScreen; - private int mBubbleBarExpandedViewDropTargetPadding; + private int mBarExpViewDropTargetPaddingTop; + private int mBarExpViewDropTargetPaddingBottom; + private int mBarExpViewDropTargetPaddingHorizontal; private PointF mRestingStackPosition; @@ -173,8 +175,12 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider { res.getDimensionPixelSize(R.dimen.bubble_bar_expanded_view_width), mPositionRect.width() - 2 * mExpandedViewPadding ); - mBubbleBarExpandedViewDropTargetPadding = res.getDimensionPixelSize( - R.dimen.bubble_bar_expanded_view_drop_target_padding); + mBarExpViewDropTargetPaddingTop = res.getDimensionPixelSize( + R.dimen.bubble_bar_expanded_view_drop_target_padding_top); + mBarExpViewDropTargetPaddingBottom = res.getDimensionPixelSize( + R.dimen.bubble_bar_expanded_view_drop_target_padding_bottom); + mBarExpViewDropTargetPaddingHorizontal = res.getDimensionPixelSize( + R.dimen.bubble_bar_expanded_view_drop_target_padding_horizontal); if (mShowingInBubbleBar) { mExpandedViewLargeScreenWidth = mExpandedViewBubbleBarWidth; @@ -986,8 +992,15 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider { public Rect getBubbleBarExpandedViewDropTargetBounds(boolean onLeft) { Rect bounds = new Rect(); getBubbleBarExpandedViewBounds(onLeft, false, bounds); - bounds.inset(mBubbleBarExpandedViewDropTargetPadding, - mBubbleBarExpandedViewDropTargetPadding); + // Drop target bounds are based on expanded view bounds with some padding added + int leftPadding = onLeft ? 0 : mBarExpViewDropTargetPaddingHorizontal; + int rightPadding = onLeft ? mBarExpViewDropTargetPaddingHorizontal : 0; + bounds.inset( + leftPadding, + mBarExpViewDropTargetPaddingTop, + rightPadding, + mBarExpViewDropTargetPaddingBottom + ); return bounds; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 92724178cf84..dd5a23aae7f9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -91,6 +91,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.shared.animation.Interpolators; import com.android.wm.shell.shared.animation.PhysicsAnimator; +import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper; import com.android.wm.shell.shared.bubbles.DeviceConfig; import com.android.wm.shell.shared.bubbles.DismissView; import com.android.wm.shell.shared.bubbles.RelativeTouchListener; @@ -1319,7 +1320,7 @@ public class BubbleStackView extends FrameLayout mBubbleContainer.bringToFront(); } - // TODO: Create ManageMenuView and move setup / animations there + // TODO (b/402196554) : Create ManageMenuView and move setup / animations there private void setUpManageMenu() { if (mManageMenu != null) { removeView(mManageMenu); @@ -1377,6 +1378,22 @@ public class BubbleStackView extends FrameLayout mManageSettingsIcon = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_icon); mManageSettingsText = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_name); + View fullscreenView = mManageMenu.findViewById( + R.id.bubble_manage_menu_fullscreen_container); + if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { + fullscreenView.setVisibility(VISIBLE); + fullscreenView.setOnClickListener( + view -> { + showManageMenu(false /* show */); + BubbleExpandedView expandedView = getExpandedView(); + if (expandedView != null && expandedView.getTaskView() != null) { + expandedView.getTaskView().moveToFullscreen(); + } + }); + } else { + fullscreenView.setVisibility(GONE); + } + // The menu itself should respect locale direction so the icons are on the correct side. mManageMenu.setLayoutDirection(LAYOUT_DIRECTION_LOCALE); addView(mManageMenu); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java index 8cd6ce020408..728975e8ef9f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java @@ -30,6 +30,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.TaskInfo; import android.content.Context; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.IBinder; @@ -42,6 +43,11 @@ import android.window.TransitionRequestInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; +import androidx.core.animation.Animator; +import androidx.core.animation.Animator.AnimatorUpdateListener; +import androidx.core.animation.AnimatorListenerAdapter; +import androidx.core.animation.ValueAnimator; + import com.android.internal.annotations.VisibleForTesting; import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.ShellTaskOrganizer; @@ -114,8 +120,8 @@ public class BubbleTransitions { } /** Starts a transition that converts a dragged bubble icon to a full screen task. */ - public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble) { - return new DraggedBubbleIconToFullscreen(bubble); + public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) { + return new DraggedBubbleIconToFullscreen(bubble, dropLocation); } /** @@ -612,8 +618,7 @@ public class BubbleTransitions { mTaskLeash = taskChg.getLeash(); mRootLeash = info.getRoot(0).getLeash(); - SurfaceControl dest = - mBubble.getBubbleBarExpandedView().getViewRootImpl().getSurfaceControl(); + SurfaceControl dest = getExpandedView(mBubble).getViewRootImpl().getSurfaceControl(); final Runnable onPlucked = () -> { // Need to remove the taskview AFTER applying the startTransaction because // it isn't synchronized. @@ -623,12 +628,12 @@ public class BubbleTransitions { mBubbleData.setExpanded(false /* expanded */); }; if (dest != null) { - pluck(mTaskLeash, mBubble.getBubbleBarExpandedView(), dest, + pluck(mTaskLeash, getExpandedView(mBubble), dest, taskChg.getStartAbsBounds().left - info.getRoot(0).getOffset().x, taskChg.getStartAbsBounds().top - info.getRoot(0).getOffset().y, - mBubble.getBubbleBarExpandedView().getCornerRadius(), startTransaction, + getCornerRadius(mBubble), startTransaction, onPlucked); - mBubble.getBubbleBarExpandedView().post(() -> mTransitions.dispatchTransition( + getExpandedView(mBubble).post(() -> mTransitions.dispatchTransition( mTransition, info, startTransaction, finishTransaction, finishCallback, null)); } else { @@ -649,6 +654,20 @@ public class BubbleTransitions { t.reparent(mTaskLeash, mRootLeash); t.apply(); } + + private View getExpandedView(@NonNull Bubble bubble) { + if (bubble.getBubbleBarExpandedView() != null) { + return bubble.getBubbleBarExpandedView(); + } + return bubble.getExpandedView(); + } + + private float getCornerRadius(@NonNull Bubble bubble) { + if (bubble.getBubbleBarExpandedView() != null) { + return bubble.getBubbleBarExpandedView().getCornerRadius(); + } + return bubble.getExpandedView().getCornerRadius(); + } } /** @@ -660,9 +679,19 @@ public class BubbleTransitions { IBinder mTransition; final Bubble mBubble; + final Point mDropLocation; + final TransactionProvider mTransactionProvider; + + DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) { + this(bubble, dropLocation, SurfaceControl.Transaction::new); + } - DraggedBubbleIconToFullscreen(Bubble bubble) { + @VisibleForTesting + DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation, + TransactionProvider transactionProvider) { mBubble = bubble; + mDropLocation = dropLocation; + mTransactionProvider = transactionProvider; bubble.setPreparingTransition(this); WindowContainerToken token = bubble.getTaskView().getTaskInfo().getToken(); WindowContainerTransaction wct = new WindowContainerTransaction(); @@ -710,8 +739,34 @@ public class BubbleTransitions { } mRepository.remove(taskViewTaskController); + final SurfaceControl taskLeash = change.getLeash(); + // set the initial position of the task with 0 scale + startTransaction.setPosition(taskLeash, mDropLocation.x, mDropLocation.y); + startTransaction.setScale(taskLeash, 0, 0); startTransaction.apply(); - finishCallback.onTransitionFinished(null); + + final SurfaceControl.Transaction animT = mTransactionProvider.get(); + ValueAnimator animator = ValueAnimator.ofFloat(0, 1); + animator.setDuration(250); + animator.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull Animator animation) { + float progress = animator.getAnimatedFraction(); + float x = mDropLocation.x * (1 - progress); + float y = mDropLocation.y * (1 - progress); + animT.setPosition(taskLeash, x, y); + animT.setScale(taskLeash, progress, progress); + animT.apply(); + } + }); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(@NonNull Animator animation) { + animT.close(); + finishCallback.onTransitionFinished(null); + } + }); + animator.start(); taskViewTaskController.notifyTaskRemovalStarted(mBubble.getTaskView().getTaskInfo()); mTaskViewTransitions.onExternalDone(transition); return true; @@ -761,4 +816,8 @@ public class BubbleTransitions { mTaskViewTransitions.onExternalDone(transition); } } + + interface TransactionProvider { + SurfaceControl.Transaction get(); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl index 079edb3ea8ec..e2d5d787cf2b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl @@ -18,6 +18,7 @@ package com.android.wm.shell.bubbles; import android.content.Intent; import android.content.pm.ShortcutInfo; +import android.graphics.Point; import android.graphics.Rect; import android.os.UserHandle; import com.android.wm.shell.bubbles.IBubblesListener; @@ -59,5 +60,5 @@ interface IBubbles { oneway void showDropTarget(in boolean show, in @nullable BubbleBarLocation location) = 15; - oneway void moveBubbleToFullscreen(in String key) = 16; + oneway void moveDraggedBubbleToFullscreen(in String key, in Point dropLocation) = 16; }
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java index b7761ec75782..69009fd1606a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java @@ -28,9 +28,9 @@ import android.view.View; import android.view.ViewGroup; import com.android.app.animation.Interpolators; -import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubble; +import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper; import java.util.ArrayList; @@ -263,7 +263,7 @@ class BubbleBarMenuViewController { } )); - if (Flags.enableBubbleAnything() || Flags.enableBubbleToFullscreen()) { + if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { menuActions.add(new BubbleBarMenuView.MenuAction( Icon.createWithResource(resources, R.drawable.desktop_mode_ic_handle_menu_fullscreen), diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java index f73788486d04..bc76a8797f83 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java @@ -468,10 +468,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } } - private void setAnimating(boolean imeAnimationOngoing) { + private void setAnimating(boolean imeAnimationOngoing, + @Nullable ImeTracker.Token statsToken) { int animatingTypes = imeAnimationOngoing ? WindowInsets.Type.ime() : 0; try { - mWmService.updateDisplayWindowAnimatingTypes(mDisplayId, animatingTypes); + mWmService.updateDisplayWindowAnimatingTypes(mDisplayId, animatingTypes, + statsToken); } catch (RemoteException e) { } } @@ -635,7 +637,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged + " showing:" + (mAnimationDirection == DIRECTION_SHOW)); } if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) { - setAnimating(true /* imeAnimationOngoing */); + // Updating the animatingTypes when starting the animation is not the + // trigger to show the IME. Thus, not sending the statsToken here. + setAnimating(true /* imeAnimationOngoing */, null /* statsToken */); } int flags = dispatchStartPositioning(mDisplayId, imeTop(hiddenY, defaultY), imeTop(shownY, defaultY), mAnimationDirection == DIRECTION_SHOW, @@ -685,7 +689,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged if (!android.view.inputmethod.Flags.refactorInsetsController()) { dispatchEndPositioning(mDisplayId, mCancelled, t); } else if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) { - setAnimating(false /* imeAnimationOngoing */); + setAnimating(false /* imeAnimationOngoing */, + mAnimationDirection == DIRECTION_HIDE ? statsToken : null); } if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) { ImeTracker.forLogging().onProgress(mStatsToken, @@ -695,7 +700,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged removeImeSurface(mDisplayId); } if (android.view.inputmethod.Flags.refactorInsetsController()) { - setVisibleDirectly(false /* visible */, statsToken); + // Updating the client visibility will not hide the IME, unless it is + // not animating anymore. Thus, not sending a statsToken here, but + // only later when we're updating the animatingTypes. + setVisibleDirectly(false /* visible */, + !android.view.inputmethod.Flags.reportAnimatingInsetsTypes() + ? statsToken : null); } if (!android.view.inputmethod.Flags.refactorInsetsController()) { ImeTracker.forLogging().onHidden(mStatsToken); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index fec1f56c76bb..2b0885ed65a1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -559,7 +559,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange true /* setEffectBounds */); } - /** Updates recording bounds of divider window and both of the splits. */ + /** + * Updates the bounds of the divider window and both split apps. + * @param position The left/top edge of the visual divider, where the edge of app A meets the + * divider. Not to be confused with the actual divider surface, which is larger + * and overlaps the apps a bit. + */ private void updateBounds(int position, Rect bounds1, Rect bounds2, Rect dividerBounds, boolean setEffectBounds) { dividerBounds.set(mRootBounds); @@ -574,10 +579,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange // For flexible split, expand app offscreen as well if (mDividerSnapAlgorithm.areOffscreenRatiosSupported()) { - if (position <= mDividerSnapAlgorithm.getMiddleTarget().position) { - bounds1.left = bounds1.right - bounds2.width(); + int distanceToCenter = position - mDividerSnapAlgorithm.getMiddleTarget().position; + if (position < mDividerSnapAlgorithm.getMiddleTarget().position) { + bounds1.left += distanceToCenter * 2; } else { - bounds2.right = bounds2.left + bounds1.width(); + bounds2.right += distanceToCenter * 2; } } @@ -590,10 +596,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange // For flexible split, expand app offscreen as well if (mDividerSnapAlgorithm.areOffscreenRatiosSupported()) { - if (position <= mDividerSnapAlgorithm.getMiddleTarget().position) { - bounds1.top = bounds1.bottom - bounds2.height(); + int distanceToCenter = position - mDividerSnapAlgorithm.getMiddleTarget().position; + if (position < mDividerSnapAlgorithm.getMiddleTarget().position) { + bounds1.top += distanceToCenter * 2; } else { - bounds2.bottom = bounds2.top + bounds1.height(); + bounds2.bottom += distanceToCenter * 2; } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt index 812cc0161aae..bcbe123eb5e6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt @@ -167,6 +167,7 @@ class LetterboxInputDetector( windowSession.updateInputChannel( inputChannel.token, + null /* hostInputTransferToken */, displayId, inputSurface, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 257e27a338be..2cf671b0f446 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -98,6 +98,7 @@ import com.android.wm.shell.desktopmode.DesktopModeKeyGestureHandler; import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver; import com.android.wm.shell.desktopmode.DesktopModeMoveToDisplayTransitionHandler; import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger; +import com.android.wm.shell.desktopmode.DesktopPipTransitionObserver; import com.android.wm.shell.desktopmode.DesktopTaskChangeListener; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.desktopmode.DesktopTasksLimiter; @@ -780,6 +781,7 @@ public abstract class WMShellModule { OverviewToDesktopTransitionObserver overviewToDesktopTransitionObserver, DesksOrganizer desksOrganizer, Optional<DesksTransitionObserver> desksTransitionObserver, + Optional<DesktopPipTransitionObserver> desktopPipTransitionObserver, UserProfileContexts userProfileContexts, DesktopModeCompatPolicy desktopModeCompatPolicy, DragToDisplayTransitionHandler dragToDisplayTransitionHandler, @@ -823,6 +825,7 @@ public abstract class WMShellModule { overviewToDesktopTransitionObserver, desksOrganizer, desksTransitionObserver.get(), + desktopPipTransitionObserver, userProfileContexts, desktopModeCompatPolicy, dragToDisplayTransitionHandler, @@ -966,8 +969,15 @@ public abstract class WMShellModule { @WMSingleton @Provides - static DesktopModeMoveToDisplayTransitionHandler provideMoveToDisplayTransitionHandler() { - return new DesktopModeMoveToDisplayTransitionHandler(new SurfaceControl.Transaction()); + static DesktopModeMoveToDisplayTransitionHandler provideMoveToDisplayTransitionHandler( + InteractionJankMonitor interactionJankMonitor, + @ShellMainThread Handler shellMainHandler, + DisplayController displayController) { + return new DesktopModeMoveToDisplayTransitionHandler( + new SurfaceControl.Transaction(), + interactionJankMonitor, + shellMainHandler, + displayController); } @WMSingleton @@ -1225,6 +1235,7 @@ public abstract class WMShellModule { Transitions transitions, ShellTaskOrganizer shellTaskOrganizer, Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler, + Optional<DesktopPipTransitionObserver> desktopPipTransitionObserver, Optional<BackAnimationController> backAnimationController, DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider, ShellInit shellInit) { @@ -1237,6 +1248,7 @@ public abstract class WMShellModule { transitions, shellTaskOrganizer, desktopMixedTransitionHandler.get(), + desktopPipTransitionObserver, backAnimationController.get(), desktopWallpaperActivityTokenProvider, shellInit))); @@ -1258,6 +1270,19 @@ public abstract class WMShellModule { @WMSingleton @Provides + static Optional<DesktopPipTransitionObserver> provideDesktopPipTransitionObserver( + Context context + ) { + if (DesktopModeStatus.canEnterDesktopMode(context) + && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) { + return Optional.of( + new DesktopPipTransitionObserver()); + } + return Optional.empty(); + } + + @WMSingleton + @Provides static Optional<DesktopMixedTransitionHandler> provideDesktopMixedTransitionHandler( Context context, Transitions transitions, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt index 6dcc0deb1da1..ea2fdc0ee8ed 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt @@ -28,6 +28,7 @@ import android.provider.Settings import android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS import android.view.Display.DEFAULT_DISPLAY import android.view.IWindowManager +import android.view.InputDevice import android.view.WindowManager.TRANSIT_CHANGE import android.window.DesktopExperienceFlags import android.window.WindowContainerTransaction @@ -62,12 +63,28 @@ class DesktopDisplayModeController( } } + private val inputDeviceListener = + object : InputManager.InputDeviceListener { + override fun onInputDeviceAdded(deviceId: Int) { + refreshDisplayWindowingMode() + } + + override fun onInputDeviceChanged(deviceId: Int) { + refreshDisplayWindowingMode() + } + + override fun onInputDeviceRemoved(deviceId: Int) { + refreshDisplayWindowingMode() + } + } + init { if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { inputManager.registerOnTabletModeChangedListener( onTabletModeChangedListener, mainHandler, ) + inputManager.registerInputDeviceListener(inputDeviceListener, mainHandler) } } @@ -114,21 +131,36 @@ class DesktopDisplayModeController( transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null) } + // Do not directly use this method to check the state of desktop-first mode. Check the display + // windowing mode instead. + private fun canDesktopFirstModeBeEnabledOnDefaultDisplay(): Boolean { + if (isDefaultDisplayDesktopEligible()) { + if (isExtendedDisplayEnabled() && hasExternalDisplay()) { + return true + } + if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { + if (isInClamshellMode() || hasAnyMouseDevice()) { + return true + } + } + } + return false + } + @VisibleForTesting fun getTargetWindowingModeForDefaultDisplay(): Int { - if (isExtendedDisplayEnabled() && hasExternalDisplay()) { + if (canDesktopFirstModeBeEnabledOnDefaultDisplay()) { return WINDOWING_MODE_FREEFORM } - if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { - if (isInClamshellMode()) { - return WINDOWING_MODE_FREEFORM - } - return WINDOWING_MODE_FULLSCREEN - } - // If form factor-based desktop first switch is disabled, use the default display windowing - // mode here to keep the freeform mode for some form factors (e.g., FEATURE_PC). - return windowManager.getWindowingMode(DEFAULT_DISPLAY) + return if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { + WINDOWING_MODE_FULLSCREEN + } else { + // If form factor-based desktop first switch is disabled, use the default display + // windowing mode here to keep the freeform mode for some form factors (e.g., + // FEATURE_PC). + windowManager.getWindowingMode(DEFAULT_DISPLAY) + } } private fun isExtendedDisplayEnabled(): Boolean { @@ -154,8 +186,20 @@ class DesktopDisplayModeController( private fun hasExternalDisplay() = rootTaskDisplayAreaOrganizer.getDisplayIds().any { it != DEFAULT_DISPLAY } + private fun hasAnyMouseDevice() = + inputManager.inputDeviceIds.any { + inputManager.getInputDevice(it)?.supportsSource(InputDevice.SOURCE_MOUSE) == true + } + private fun isInClamshellMode() = inputManager.isInTabletMode() == InputManager.SWITCH_STATE_OFF + private fun isDefaultDisplayDesktopEligible(): Boolean { + val display = requireNotNull(displayController.getDisplay(DEFAULT_DISPLAY)) { + "Display object of DEFAULT_DISPLAY must be non-null." + } + return DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display) + } + private fun logV(msg: String, vararg arguments: Any?) { ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt index 91bd3c9b6c22..844a1f896fd2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt @@ -19,19 +19,26 @@ package com.android.wm.shell.desktopmode import android.animation.Animator import android.animation.AnimatorSet import android.animation.ValueAnimator +import android.os.Handler import android.os.IBinder import android.view.Choreographer import android.view.SurfaceControl import android.window.TransitionInfo import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction +import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY +import com.android.internal.jank.InteractionJankMonitor +import com.android.wm.shell.common.DisplayController import com.android.wm.shell.shared.animation.Interpolators import com.android.wm.shell.transition.Transitions import kotlin.time.Duration.Companion.milliseconds /** Transition handler for moving a window to a different display. */ class DesktopModeMoveToDisplayTransitionHandler( - private val animationTransaction: SurfaceControl.Transaction + private val animationTransaction: SurfaceControl.Transaction, + private val interactionJankMonitor: InteractionJankMonitor, + private val shellMainHandler: Handler, + private val displayController: DisplayController, ) : Transitions.TransitionHandler { override fun handleRequest( @@ -74,18 +81,31 @@ class DesktopModeMoveToDisplayTransitionHandler( } } ) + animator.addListener( object : Animator.AnimatorListener { - override fun onAnimationStart(animation: Animator) = Unit + override fun onAnimationStart(animation: Animator) { + val displayContext = + displayController.getDisplayContext(changes[0].endDisplayId) + if (displayContext == null) return + interactionJankMonitor.begin( + changes[0].leash, + displayContext, + shellMainHandler, + CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY, + ) + } override fun onAnimationEnd(animation: Animator) { finishTransaction.apply() finishCallback.onTransitionFinished(null) + interactionJankMonitor.end(CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY) } override fun onAnimationCancel(animation: Animator) { finishTransaction.apply() finishCallback.onTransitionFinished(null) + interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY) } override fun onAnimationRepeat(animation: Animator) = Unit diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java index 1938e76cad49..1c5138f486e4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java @@ -21,10 +21,13 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static com.android.internal.policy.SystemBarUtils.getDesktopViewAppHeaderHeightPx; import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR; +import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR; +import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR; import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR; import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR; import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR; import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR; +import static com.android.wm.shell.shared.ShellSharedConstants.SMALL_TABLET_MAX_EDGE_DP; import android.annotation.NonNull; import android.annotation.Nullable; @@ -33,6 +36,7 @@ import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.Region; +import android.util.Pair; import android.view.Display; import android.view.SurfaceControl; import android.window.DesktopModeFlags; @@ -46,13 +50,17 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; +import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.shared.annotations.ShellDesktopThread; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper; import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider; -import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.windowdecor.tiling.SnapEventHandler; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + /** * Animated visual indicator for Desktop Mode windowing transitions. */ @@ -116,12 +124,20 @@ public class DesktopModeVisualIndicator { private final Context mContext; private final DisplayController mDisplayController; private final ActivityManager.RunningTaskInfo mTaskInfo; - private final Display mDisplay; private IndicatorType mCurrentType; private final DragStartState mDragStartState; private final SnapEventHandler mSnapEventHandler; + private final boolean mUseSmallTabletRegions; + /** + * Ordered list of {@link Rect} zones that we will match an input coordinate against. + * List is traversed from first to last element. The first rect that contains the input event + * will be used and the matching {@link IndicatorType} is returned. + * Empty rect matches all. + */ + private final List<Pair<Rect, IndicatorType>> mSortedRegions; + public DesktopModeVisualIndicator(@ShellDesktopThread ShellExecutor desktopExecutor, @ShellMainThread ShellExecutor mainExecutor, SyncTransactionQueue syncQueue, @@ -131,6 +147,24 @@ public class DesktopModeVisualIndicator { DragStartState dragStartState, @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider, SnapEventHandler snapEventHandler) { + this(desktopExecutor, mainExecutor, syncQueue, taskInfo, displayController, context, + taskSurface, taskDisplayAreaOrganizer, dragStartState, bubbleBoundsProvider, + snapEventHandler, useSmallTabletRegions(displayController, taskInfo), + isLeftRightSplit(context, displayController, taskInfo)); + } + + @VisibleForTesting + DesktopModeVisualIndicator(@ShellDesktopThread ShellExecutor desktopExecutor, + @ShellMainThread ShellExecutor mainExecutor, + SyncTransactionQueue syncQueue, + ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController, + Context context, SurfaceControl taskSurface, + RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer, + DragStartState dragStartState, + @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider, + SnapEventHandler snapEventHandler, + boolean useSmallTabletRegions, + boolean isLeftRightSplit) { SurfaceControl.Builder builder = new SurfaceControl.Builder(); if (!DragStartState.isDragToDesktopStartState(dragStartState) || !DesktopModeFlags.ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX.isTrue()) { @@ -148,14 +182,46 @@ public class DesktopModeVisualIndicator { mCurrentType = NO_INDICATOR; mDragStartState = dragStartState; mSnapEventHandler = snapEventHandler; - mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId); + Display display = mDisplayController.getDisplay(mTaskInfo.displayId); + DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mTaskInfo.displayId); mVisualIndicatorViewContainer.createView( mContext, - mDisplay, - mDisplayController.getDisplayLayout(mTaskInfo.displayId), + display, + displayLayout, mTaskInfo, taskSurface ); + + mUseSmallTabletRegions = useSmallTabletRegions; + + if (useSmallTabletRegions) { + mSortedRegions = initSmallTabletRegions(displayLayout, isLeftRightSplit); + } else { + // TODO(b/401596837): add support for initializing regions for large tablets + mSortedRegions = Collections.emptyList(); + } + } + + private static boolean useSmallTabletRegions(DisplayController displayController, + ActivityManager.RunningTaskInfo taskInfo) { + if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { + // Small tablet regions get enabled with bubbles feature + return false; + } + Display display = displayController.getDisplay(taskInfo.displayId); + DisplayLayout displayLayout = displayController.getDisplayLayout(taskInfo.displayId); + if (displayLayout == null) return false; + return displayLayout.pxToDp(display.getMaximumSizeDimension()) < SMALL_TABLET_MAX_EDGE_DP; + } + + private static boolean isLeftRightSplit(Context context, DisplayController displayController, + ActivityManager.RunningTaskInfo taskInfo) { + DisplayLayout layout = displayController.getDisplayLayout(taskInfo.displayId); + boolean landscape = layout != null && layout.isLandscape(); + boolean leftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait( + context.getResources()); + return SplitScreenUtils.isLeftRightSplit(leftRightSplitInPortrait, + /* isLargeScreen= */ true, landscape); } /** Start the fade out animation, running the callback on the main thread once it is done. */ @@ -191,33 +257,44 @@ public class DesktopModeVisualIndicator { */ @NonNull IndicatorType updateIndicatorType(PointF inputCoordinates) { + final IndicatorType result; + if (mUseSmallTabletRegions) { + result = getIndicatorSmallTablet(inputCoordinates); + } else { + result = getIndicatorLargeTablet(inputCoordinates); + } + if (mDragStartState != DragStartState.DRAGGED_INTENT) { + mVisualIndicatorViewContainer.transitionIndicator( + mTaskInfo, mDisplayController, mCurrentType, result + ); + mCurrentType = result; + } + return result; + } + + @NonNull + private IndicatorType getIndicatorLargeTablet(PointF inputCoordinates) { + // TODO(b/401596837): cache the regions to avoid recalculating on each motion event final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId); // Perform a quick check first: any input off the left edge of the display should be split // left, and split right for the right edge. This is universal across all drag event types. if (inputCoordinates.x < 0) return TO_SPLIT_LEFT_INDICATOR; if (inputCoordinates.x > layout.width()) return TO_SPLIT_RIGHT_INDICATOR; - IndicatorType result; - if (BubbleAnythingFlagHelper.enableBubbleToFullscreen() - && !DesktopModeStatus.isDesktopModeSupportedOnDisplay(mContext, mDisplay)) { - // If desktop is not available, default to "no indicator" - result = NO_INDICATOR; - } else { - // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone. - // In drags not originating on a freeform caption, we should default to a TO_DESKTOP - // indicator. - result = mDragStartState == DragStartState.FROM_FREEFORM + // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone. + // In drags not originating on a freeform caption, we should default to a TO_DESKTOP + // indicator. + IndicatorType result = mDragStartState == DragStartState.FROM_FREEFORM ? NO_INDICATOR : TO_DESKTOP_INDICATOR; - } final int transitionAreaWidth = mContext.getResources().getDimensionPixelSize( com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness); // Because drags in freeform use task position for indicator calculation, we need to // account for the possibility of the task going off the top of the screen by captionHeight final int captionHeight = getDesktopViewAppHeaderHeightPx(mContext); final Region fullscreenRegion = calculateFullscreenRegion(layout, captionHeight); - final Region splitLeftRegion = calculateSplitLeftRegion(layout, transitionAreaWidth, + final Rect splitLeftRegion = calculateSplitLeftRegion(layout, transitionAreaWidth, captionHeight); - final Region splitRightRegion = calculateSplitRightRegion(layout, transitionAreaWidth, + final Rect splitRightRegion = calculateSplitRightRegion(layout, transitionAreaWidth, captionHeight); final int x = (int) inputCoordinates.x; final int y = (int) inputCoordinates.y; @@ -234,18 +311,23 @@ public class DesktopModeVisualIndicator { if (calculateBubbleLeftRegion(layout).contains(x, y)) { result = IndicatorType.TO_BUBBLE_LEFT_INDICATOR; } else if (calculateBubbleRightRegion(layout).contains(x, y)) { - result = IndicatorType.TO_BUBBLE_RIGHT_INDICATOR; + result = TO_BUBBLE_RIGHT_INDICATOR; } } - if (mDragStartState != DragStartState.DRAGGED_INTENT) { - mVisualIndicatorViewContainer.transitionIndicator( - mTaskInfo, mDisplayController, mCurrentType, result - ); - mCurrentType = result; - } return result; } + @NonNull + private IndicatorType getIndicatorSmallTablet(PointF inputCoordinates) { + for (Pair<Rect, IndicatorType> region : mSortedRegions) { + if (region.first.isEmpty()) return region.second; // empty rect matches all + if (region.first.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) { + return region.second; + } + } + return NO_INDICATOR; + } + /** * Returns the [DragStartState] of the visual indicator. */ @@ -284,53 +366,79 @@ public class DesktopModeVisualIndicator { } @VisibleForTesting - Region calculateSplitLeftRegion(DisplayLayout layout, + Rect calculateSplitLeftRegion(DisplayLayout layout, int transitionEdgeWidth, int captionHeight) { - final Region region = new Region(); // In freeform, keep the top corners clear. int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM ? mContext.getResources().getDimensionPixelSize( com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) : -captionHeight; - region.union(new Rect(0, transitionHeight, transitionEdgeWidth, layout.height())); - return region; + return new Rect(0, transitionHeight, transitionEdgeWidth, layout.height()); } @VisibleForTesting - Region calculateSplitRightRegion(DisplayLayout layout, + Rect calculateSplitRightRegion(DisplayLayout layout, int transitionEdgeWidth, int captionHeight) { - final Region region = new Region(); // In freeform, keep the top corners clear. int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM ? mContext.getResources().getDimensionPixelSize( com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) : -captionHeight; - region.union(new Rect(layout.width() - transitionEdgeWidth, transitionHeight, - layout.width(), layout.height())); - return region; + return new Rect(layout.width() - transitionEdgeWidth, transitionHeight, + layout.width(), layout.height()); } @VisibleForTesting - Region calculateBubbleLeftRegion(DisplayLayout layout) { - int regionWidth = mContext.getResources().getDimensionPixelSize( - com.android.wm.shell.R.dimen.bubble_transform_area_width); - int regionHeight = mContext.getResources().getDimensionPixelSize( - com.android.wm.shell.R.dimen.bubble_transform_area_height); - return new Region(0, layout.height() - regionHeight, regionWidth, layout.height()); + Rect calculateBubbleLeftRegion(DisplayLayout layout) { + int regionSize = getBubbleRegionSize(); + return new Rect(0, layout.height() - regionSize, regionSize, layout.height()); } @VisibleForTesting - Region calculateBubbleRightRegion(DisplayLayout layout) { - int regionWidth = mContext.getResources().getDimensionPixelSize( - com.android.wm.shell.R.dimen.bubble_transform_area_width); - int regionHeight = mContext.getResources().getDimensionPixelSize( - com.android.wm.shell.R.dimen.bubble_transform_area_height); - return new Region(layout.width() - regionWidth, layout.height() - regionHeight, + Rect calculateBubbleRightRegion(DisplayLayout layout) { + int regionSize = getBubbleRegionSize(); + return new Rect(layout.width() - regionSize, layout.height() - regionSize, layout.width(), layout.height()); } + private int getBubbleRegionSize() { + int resId = mUseSmallTabletRegions + ? com.android.wm.shell.shared.R.dimen.drag_zone_bubble_fold + : com.android.wm.shell.shared.R.dimen.drag_zone_bubble_tablet; + return mContext.getResources().getDimensionPixelSize(resId); + } + @VisibleForTesting Rect getIndicatorBounds() { return mVisualIndicatorViewContainer.getIndicatorBounds(); } + + private List<Pair<Rect, IndicatorType>> initSmallTabletRegions(DisplayLayout layout, + boolean isLeftRightSplit) { + boolean dragFromFullscreen = mDragStartState == DragStartState.FROM_FULLSCREEN; + boolean dragFromSplit = mDragStartState == DragStartState.FROM_SPLIT; + if (isLeftRightSplit && (dragFromFullscreen || dragFromSplit)) { + int splitRegionWidth = mContext.getResources().getDimensionPixelSize( + com.android.wm.shell.shared.R.dimen.drag_zone_h_split_from_app_width_fold); + return Arrays.asList( + new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR), + new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR), + new Pair<>(calculateSplitLeftRegion(layout, splitRegionWidth, + /* captionHeight= */ 0), TO_SPLIT_LEFT_INDICATOR), + new Pair<>(calculateSplitRightRegion(layout, splitRegionWidth, + /* captionHeight= */ 0), TO_SPLIT_RIGHT_INDICATOR), + new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR) // default to fullscreen + ); + } + if (dragFromFullscreen) { + // If left/right split is not available, we can only drag fullscreen tasks + // TODO(b/401352409): add support for top/bottom split zones + return Arrays.asList( + new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR), + new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR), + new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR) // default to fullscreen + ); + } + return Collections.emptyList(); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt new file mode 100644 index 000000000000..efd3866e1bc4 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2025 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.desktopmode + +import android.app.WindowConfiguration.WINDOWING_MODE_PINNED +import android.os.IBinder +import android.window.DesktopModeFlags +import android.window.TransitionInfo +import com.android.internal.protolog.ProtoLog +import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE + +/** + * Observer of PiP in Desktop Mode transitions. At the moment, this is specifically tracking a PiP + * transition for a task that is entering PiP via the minimize button on the caption bar. + */ +class DesktopPipTransitionObserver { + private val pendingPipTransitions = mutableMapOf<IBinder, PendingPipTransition>() + + /** Adds a pending PiP transition to be tracked. */ + fun addPendingPipTransition(transition: PendingPipTransition) { + if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) return + pendingPipTransitions[transition.token] = transition + } + + /** + * Called when any transition is ready, which may include transitions not tracked by this + * observer. + */ + fun onTransitionReady(transition: IBinder, info: TransitionInfo) { + if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) return + val pipTransition = pendingPipTransitions.remove(transition) ?: return + + logD("Desktop PiP transition ready: %s", transition) + for (change in info.changes) { + val taskInfo = change.taskInfo + if (taskInfo == null || taskInfo.taskId == -1) { + continue + } + + if ( + taskInfo.taskId == pipTransition.taskId && + taskInfo.windowingMode == WINDOWING_MODE_PINNED + ) { + logD("Desktop PiP transition was successful") + pipTransition.onSuccess() + return + } + } + logD("Change with PiP task not found in Desktop PiP transition; likely failed") + } + + /** + * Data tracked for a pending PiP transition. + * + * @property token the PiP transition that is started. + * @property taskId task id of the task entering PiP. + * @property onSuccess callback to be invoked if the PiP transition is successful. + */ + data class PendingPipTransition(val token: IBinder, val taskId: Int, val onSuccess: () -> Unit) + + private fun logD(msg: String, vararg arguments: Any?) { + ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) + } + + private companion object { + private const val TAG = "DesktopPipTransitionObserver" + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt index a4e9c52ac9d9..e77acfb805a6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt @@ -68,7 +68,8 @@ class DesktopRepository( * @property topTransparentFullscreenTaskId the task id of any current top transparent * fullscreen task launched on top of the desk. Cleared when the transparent task is closed or * sent to back. (top is at index 0). - * @property pipTaskId the task id of PiP task entered while in Desktop Mode. + * @property leftTiledTaskId task id of the task tiled on the left. + * @property rightTiledTaskId task id of the task tiled on the right. */ private data class Desk( val deskId: Int, @@ -81,7 +82,8 @@ class DesktopRepository( val freeformTasksInZOrder: ArrayList<Int> = ArrayList(), var fullImmersiveTaskId: Int? = null, var topTransparentFullscreenTaskId: Int? = null, - var pipTaskId: Int? = null, + var leftTiledTaskId: Int? = null, + var rightTiledTaskId: Int? = null, ) { fun deepCopy(): Desk = Desk( @@ -94,7 +96,8 @@ class DesktopRepository( freeformTasksInZOrder = ArrayList(freeformTasksInZOrder), fullImmersiveTaskId = fullImmersiveTaskId, topTransparentFullscreenTaskId = topTransparentFullscreenTaskId, - pipTaskId = pipTaskId, + leftTiledTaskId = leftTiledTaskId, + rightTiledTaskId = rightTiledTaskId, ) // TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't @@ -107,7 +110,8 @@ class DesktopRepository( freeformTasksInZOrder.clear() fullImmersiveTaskId = null topTransparentFullscreenTaskId = null - pipTaskId = null + leftTiledTaskId = null + rightTiledTaskId = null } } @@ -127,9 +131,6 @@ class DesktopRepository( /* Tracks last bounds of task before toggled to immersive state. */ private val boundsBeforeFullImmersiveByTaskId = SparseArray<Rect>() - /* Callback for when a pending PiP transition has been aborted. */ - private var onPipAbortedCallback: ((Int, Int) -> Unit)? = null - private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionExecutor: Executor? = null @@ -275,6 +276,106 @@ class DesktopRepository( } } + /** Register a left tiled task to desktop state. */ + fun addLeftTiledTask(displayId: Int, taskId: Int) { + logD("addLeftTiledTask for displayId=%d, taskId=%d", displayId, taskId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + addLeftTiledTaskToDesk(displayId, taskId, activeDesk.deskId) + } + + private fun addLeftTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) { + logD("addLeftTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.leftTiledTaskId = taskId + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + + /** Register a right tiled task to desktop state. */ + fun addRightTiledTask(displayId: Int, taskId: Int) { + logD("addRightTiledTask for displayId=%d, taskId=%d", displayId, taskId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + addRightTiledTaskToDesk(displayId, taskId, activeDesk.deskId) + } + + private fun addRightTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) { + logD("addRightTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.rightTiledTaskId = taskId + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + + /** Gets a registered left tiled task to desktop state or returns null. */ + fun getLeftTiledTask(displayId: Int): Int? { + logD("getLeftTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + val deskId = activeDesk.deskId + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + return desk.leftTiledTaskId + } + + /** gets a registered right tiled task to desktop state or returns null. */ + fun getRightTiledTask(displayId: Int): Int? { + logD("getRightTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + val deskId = activeDesk.deskId + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + return desk.rightTiledTaskId + } + + /* Unregisters a left tiled task from desktop state. */ + fun removeLeftTiledTask(displayId: Int) { + logD("removeLeftTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + removeLeftTiledTaskFromDesk(displayId, activeDesk.deskId) + } + + private fun removeLeftTiledTaskFromDesk(displayId: Int, deskId: Int) { + logD("removeLeftTiledTaskToDesk for displayId=%d", displayId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.leftTiledTaskId = null + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + + /* Unregisters a right tiled task from desktop state. */ + fun removeRightTiledTask(displayId: Int) { + logD("removeRightTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + removeRightTiledTaskFromDesk(displayId, activeDesk.deskId) + } + + private fun removeRightTiledTaskFromDesk(displayId: Int, deskId: Int) { + logD("removeRightTiledTaskFromDesk for displayId=%d", displayId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.rightTiledTaskId = null + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + /** Returns the id of the active desk in the given display, if any. */ fun getActiveDeskId(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.deskId @@ -611,57 +712,6 @@ class DesktopRepository( } /** - * Set whether the given task is the Desktop-entered PiP task in this display's active desk. - * - * TODO: b/389960283 - add explicit [deskId] argument. - */ - fun setTaskInPip(displayId: Int, taskId: Int, enterPip: Boolean) { - val activeDesk = - desktopData.getActiveDesk(displayId) - ?: error("Expected active desk in display: $displayId") - if (enterPip) { - activeDesk.pipTaskId = taskId - } else { - activeDesk.pipTaskId = - if (activeDesk.pipTaskId == taskId) null - else { - logW( - "setTaskInPip: taskId=%d did not match saved taskId=%d", - taskId, - activeDesk.pipTaskId, - ) - activeDesk.pipTaskId - } - } - } - - /** - * Returns whether the given task is the Desktop-entered PiP task in this display's active desk. - * - * TODO: b/389960283 - add explicit [deskId] argument. - */ - fun isTaskMinimizedPipInDisplay(displayId: Int, taskId: Int): Boolean = - desktopData.getActiveDesk(displayId)?.pipTaskId == taskId - - /** - * Saves callback to handle a pending PiP transition being aborted. - * - * TODO: b/389960283 - add explicit [deskId] argument. - */ - fun setOnPipAbortedCallback(callbackIfPipAborted: ((displayId: Int, pipTaskId: Int) -> Unit)?) { - onPipAbortedCallback = callbackIfPipAborted - } - - /** - * Invokes callback to handle a pending PiP transition with the given task id being aborted. - * - * TODO: b/389960283 - add explicit [deskId] argument. - */ - fun onPipAborted(displayId: Int, pipTaskId: Int) { - onPipAbortedCallback?.invoke(displayId, pipTaskId) - } - - /** * Set whether the given task is the full-immersive task in this display's active desk. * * TODO: b/389960283 - consider forcing callers to use [setTaskInFullImmersiveStateInDesk] with @@ -1030,6 +1080,8 @@ class DesktopRepository( visibleTasks = desk.visibleTasks, minimizedTasks = desk.minimizedTasks, freeformTasksInZOrder = desk.freeformTasksInZOrder, + leftTiledTask = desk.leftTiledTaskId, + rightTiledTask = desk.rightTiledTaskId, ) } catch (exception: Exception) { logE( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 5e9cd9016d92..0920f274f51d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -214,6 +214,7 @@ class DesktopTasksController( private val overviewToDesktopTransitionObserver: OverviewToDesktopTransitionObserver, private val desksOrganizer: DesksOrganizer, private val desksTransitionObserver: DesksTransitionObserver, + private val desktopPipTransitionObserver: Optional<DesktopPipTransitionObserver>, private val userProfileContexts: UserProfileContexts, private val desktopModeCompatPolicy: DesktopModeCompatPolicy, private val dragToDisplayTransitionHandler: DragToDisplayTransitionHandler, @@ -305,6 +306,8 @@ class DesktopTasksController( this, ) shellController.addUserChangeListener(this) + // Update the current user id again because it might be updated between init and onInit(). + updateCurrentUser(ActivityManager.getCurrentUser()) transitions.addHandler(this) dragToDesktopTransitionHandler.dragToDesktopStateListener = dragToDesktopStateListener recentsTransitionHandler.addTransitionStateListener( @@ -793,10 +796,31 @@ class DesktopTasksController( fun minimizeTask(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) { val wct = WindowContainerTransaction() - + val taskId = taskInfo.taskId + val displayId = taskInfo.displayId + val deskId = + taskRepository.getDeskIdForTask(taskInfo.taskId) + ?: if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { + logW("minimizeTask: desk not found for task: ${taskInfo.taskId}") + return + } else { + getDefaultDeskId(taskInfo.displayId) + } + val isLastTask = + if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { + taskRepository.isOnlyVisibleNonClosingTaskInDesk( + taskId = taskId, + deskId = checkNotNull(deskId) { "Expected non-null deskId" }, + displayId = displayId, + ) + } else { + taskRepository.isOnlyVisibleNonClosingTask(taskId = taskId, displayId = displayId) + } val isMinimizingToPip = DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue && - (taskInfo.pictureInPictureParams?.isAutoEnterEnabled() ?: false) + desktopPipTransitionObserver.isPresent && + (taskInfo.pictureInPictureParams?.isAutoEnterEnabled ?: false) + // If task is going to PiP, start a PiP transition instead of a minimize transition if (isMinimizingToPip) { val requestInfo = @@ -810,75 +834,63 @@ class DesktopTasksController( ) val requestRes = transitions.dispatchRequest(Binder(), requestInfo, /* skip= */ null) wct.merge(requestRes.second, true) - freeformTaskTransitionStarter.startPipTransition(wct) - taskRepository.setTaskInPip(taskInfo.displayId, taskInfo.taskId, enterPip = true) - taskRepository.setOnPipAbortedCallback { displayId, taskId -> - minimizeTaskInner(shellTaskOrganizer.getRunningTaskInfo(taskId)!!, minimizeReason) - taskRepository.setTaskInPip(displayId, taskId, enterPip = false) - } - return - } - minimizeTaskInner(taskInfo, minimizeReason) - } - - private fun minimizeTaskInner(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) { - val taskId = taskInfo.taskId - val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) - if (deskId == null && DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { - logW("minimizeTaskInner: desk not found for task: ${taskInfo.taskId}") - return - } - val displayId = taskInfo.displayId - val wct = WindowContainerTransaction() - - snapEventHandler.removeTaskIfTiled(displayId, taskId) - val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false) - val desktopExitRunnable = - performDesktopExitCleanUp( - wct = wct, - deskId = deskId, - displayId = displayId, - willExitDesktop = willExitDesktop, - ) - // Notify immersive handler as it might need to exit immersive state. - val exitResult = - desktopImmersiveController.exitImmersiveIfApplicable( - wct = wct, - taskInfo = taskInfo, - reason = DesktopImmersiveController.ExitReason.MINIMIZED, - ) - if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { - desksOrganizer.minimizeTask( - wct = wct, - deskId = checkNotNull(deskId) { "Expected non-null deskId" }, - task = taskInfo, + desktopPipTransitionObserver.get().addPendingPipTransition( + DesktopPipTransitionObserver.PendingPipTransition( + token = freeformTaskTransitionStarter.startPipTransition(wct), + taskId = taskInfo.taskId, + onSuccess = { + onDesktopTaskEnteredPip( + taskId = taskId, + deskId = deskId, + displayId = taskInfo.displayId, + taskIsLastVisibleTaskBeforePip = isLastTask, + ) + }, + ) ) } else { - wct.reorder(taskInfo.token, /* onTop= */ false) - } - val isLastTask = + snapEventHandler.removeTaskIfTiled(displayId, taskId) + val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false) + val desktopExitRunnable = + performDesktopExitCleanUp( + wct = wct, + deskId = deskId, + displayId = displayId, + willExitDesktop = willExitDesktop, + ) + // Notify immersive handler as it might need to exit immersive state. + val exitResult = + desktopImmersiveController.exitImmersiveIfApplicable( + wct = wct, + taskInfo = taskInfo, + reason = DesktopImmersiveController.ExitReason.MINIMIZED, + ) if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { - taskRepository.isOnlyVisibleNonClosingTaskInDesk( - taskId = taskId, + desksOrganizer.minimizeTask( + wct = wct, deskId = checkNotNull(deskId) { "Expected non-null deskId" }, - displayId = displayId, + task = taskInfo, ) } else { - taskRepository.isOnlyVisibleNonClosingTask(taskId = taskId, displayId = displayId) + wct.reorder(taskInfo.token, /* onTop= */ false) } - val transition = - freeformTaskTransitionStarter.startMinimizedModeTransition(wct, taskId, isLastTask) - desktopTasksLimiter.ifPresent { - it.addPendingMinimizeChange( - transition = transition, - displayId = displayId, - taskId = taskId, - minimizeReason = minimizeReason, - ) + val transition = + freeformTaskTransitionStarter.startMinimizedModeTransition(wct, taskId, isLastTask) + desktopTasksLimiter.ifPresent { + it.addPendingMinimizeChange( + transition = transition, + displayId = displayId, + taskId = taskId, + minimizeReason = minimizeReason, + ) + } + exitResult.asExit()?.runOnTransitionStart?.invoke(transition) + desktopExitRunnable?.invoke(transition) } - exitResult.asExit()?.runOnTransitionStart?.invoke(transition) - desktopExitRunnable?.invoke(transition) + taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( + doesAnyTaskRequireTaskbarRounding(displayId, taskId) + ) } /** Move a task with given `taskId` to fullscreen */ @@ -1324,6 +1336,9 @@ class DesktopTasksController( val stageCoordinatorRootTaskToken = splitScreenController.multiDisplayProvider.getDisplayRootForDisplayId(DEFAULT_DISPLAY) + if (stageCoordinatorRootTaskToken == null) { + return + } wct.reparent(stageCoordinatorRootTaskToken, displayAreaInfo.token, true /* onTop */) val deactivationRunnable = @@ -1845,7 +1860,11 @@ class DesktopTasksController( displayId: Int, forceExitDesktop: Boolean, ): Boolean { - if (forceExitDesktop && DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { + if ( + forceExitDesktop && + (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue || + DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) + ) { // |forceExitDesktop| is true when the callers knows we'll exit desktop, such as when // explicitly going fullscreen, so there's no point in checking the desktop state. return true @@ -1862,6 +1881,33 @@ class DesktopTasksController( return true } + /** Potentially perform Desktop cleanup after a task successfully enters PiP. */ + @VisibleForTesting + fun onDesktopTaskEnteredPip( + taskId: Int, + deskId: Int, + displayId: Int, + taskIsLastVisibleTaskBeforePip: Boolean, + ) { + if ( + !willExitDesktop(taskId, displayId, forceExitDesktop = taskIsLastVisibleTaskBeforePip) + ) { + return + } + + val wct = WindowContainerTransaction() + val desktopExitRunnable = + performDesktopExitCleanUp( + wct = wct, + deskId = deskId, + displayId = displayId, + willExitDesktop = true, + ) + + val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null) + desktopExitRunnable?.invoke(transition) + } + private fun performDesktopExitCleanupIfNeeded( taskId: Int, deskId: Int? = null, @@ -3503,9 +3549,15 @@ class DesktopTasksController( // TODO(b/366397912): Support full multi-user mode in Windowing. override fun onUserChanged(newUserId: Int, userContext: Context) { logV("onUserChanged previousUserId=%d, newUserId=%d", userId, newUserId) + updateCurrentUser(newUserId) + } + + private fun updateCurrentUser(newUserId: Int) { userId = newUserId taskRepository = userRepositories.getProfile(userId) - snapEventHandler.onUserChange() + if (this::snapEventHandler.isInitialized) { + snapEventHandler.onUserChange() + } } /** Called when a task's info changes. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt index 2ec6105e5af9..df4d18f8c803 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt @@ -23,7 +23,6 @@ import android.os.IBinder import android.view.SurfaceControl import android.view.WindowManager.TRANSIT_CLOSE import android.view.WindowManager.TRANSIT_OPEN -import android.view.WindowManager.TRANSIT_PIP import android.view.WindowManager.TRANSIT_TO_BACK import android.window.DesktopExperienceFlags import android.window.DesktopModeFlags @@ -43,8 +42,7 @@ import com.android.wm.shell.shared.TransitionUtil.isOpeningMode import com.android.wm.shell.shared.desktopmode.DesktopModeStatus import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.Transitions -import com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP -import com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP +import java.util.Optional /** * A [Transitions.TransitionObserver] that observes shell transitions and updates the @@ -57,6 +55,7 @@ class DesktopTasksTransitionObserver( private val transitions: Transitions, private val shellTaskOrganizer: ShellTaskOrganizer, private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler, + private val desktopPipTransitionObserver: Optional<DesktopPipTransitionObserver>, private val backAnimationController: BackAnimationController, private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider, shellInit: ShellInit, @@ -65,8 +64,6 @@ class DesktopTasksTransitionObserver( data class CloseWallpaperTransition(val transition: IBinder, val displayId: Int) private var transitionToCloseWallpaper: CloseWallpaperTransition? = null - /* Pending PiP transition and its associated display id and task id. */ - private var pendingPipTransitionAndPipTask: Triple<IBinder, Int, Int>? = null private var currentProfileId: Int init { @@ -100,33 +97,7 @@ class DesktopTasksTransitionObserver( removeTaskIfNeeded(info) } removeWallpaperOnLastTaskClosingIfNeeded(transition, info) - - val desktopRepository = desktopUserRepositories.getProfile(currentProfileId) - info.changes.forEach { change -> - change.taskInfo?.let { taskInfo -> - if ( - DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue && - desktopRepository.isTaskMinimizedPipInDisplay( - taskInfo.displayId, - taskInfo.taskId, - ) - ) { - when (info.type) { - TRANSIT_PIP -> - pendingPipTransitionAndPipTask = - Triple(transition, taskInfo.displayId, taskInfo.taskId) - - TRANSIT_EXIT_PIP, - TRANSIT_REMOVE_PIP -> - desktopRepository.setTaskInPip( - taskInfo.displayId, - taskInfo.taskId, - enterPip = false, - ) - } - } - } - } + desktopPipTransitionObserver.ifPresent { it.onTransitionReady(transition, info) } } private fun removeTaskIfNeeded(info: TransitionInfo) { @@ -301,18 +272,6 @@ class DesktopTasksTransitionObserver( } } transitionToCloseWallpaper = null - } else if (pendingPipTransitionAndPipTask?.first == transition) { - val desktopRepository = desktopUserRepositories.getProfile(currentProfileId) - if (aborted) { - pendingPipTransitionAndPipTask?.let { - desktopRepository.onPipAborted( - /*displayId=*/ it.second, - /* taskId=*/ it.third, - ) - } - } - desktopRepository.setOnPipAbortedCallback(null) - pendingPipTransitionAndPipTask = null } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt index f71eacab518d..e04a5cdb8a38 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt @@ -113,6 +113,8 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis visibleTasks: ArraySet<Int> = ArraySet(), minimizedTasks: ArraySet<Int> = ArraySet(), freeformTasksInZOrder: ArrayList<Int> = ArrayList(), + leftTiledTask: Int? = null, + rightTiledTask: Int? = null, ) { // TODO: b/367609270 - Improve the API to support multi-user try { @@ -125,7 +127,13 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis val desktop = getDesktop(currentRepository, desktopId) .toBuilder() - .updateTaskStates(visibleTasks, minimizedTasks, freeformTasksInZOrder) + .updateTaskStates( + visibleTasks, + minimizedTasks, + freeformTasksInZOrder, + leftTiledTask, + rightTiledTask, + ) .updateZOrder(freeformTasksInZOrder) persistentRepositories @@ -222,6 +230,8 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis visibleTasks: ArraySet<Int>, minimizedTasks: ArraySet<Int>, freeformTasksInZOrder: ArrayList<Int>, + leftTiledTask: Int?, + rightTiledTask: Int?, ): Desktop.Builder { clearTasksByTaskId() @@ -238,7 +248,11 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis } putAllTasksByTaskId( visibleTasks.associateWith { - createDesktopTask(it, state = DesktopTaskState.VISIBLE) + createDesktopTask( + it, + state = DesktopTaskState.VISIBLE, + getTilingStateForTask(it, leftTiledTask, rightTiledTask), + ) } ) putAllTasksByTaskId( @@ -249,6 +263,17 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis return this } + private fun getTilingStateForTask( + taskId: Int, + leftTiledTask: Int?, + rightTiledTask: Int?, + ): DesktopTaskTilingState = + when (taskId) { + leftTiledTask -> DesktopTaskTilingState.LEFT + rightTiledTask -> DesktopTaskTilingState.RIGHT + else -> DesktopTaskTilingState.NONE + } + private fun Desktop.Builder.updateZOrder( freeformTasksInZOrder: ArrayList<Int> ): Desktop.Builder { @@ -260,7 +285,12 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis private fun createDesktopTask( taskId: Int, state: DesktopTaskState = DesktopTaskState.VISIBLE, + tiling_state: DesktopTaskTilingState = DesktopTaskTilingState.NONE, ): DesktopTask = - DesktopTask.newBuilder().setTaskId(taskId).setDesktopTaskState(state).build() + DesktopTask.newBuilder() + .setTaskId(taskId) + .setDesktopTaskState(state) + .setDesktopTaskTilingState(tiling_state) + .build() } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt index 49cb7391fe97..5ed0b1d1616f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt @@ -126,6 +126,20 @@ class DesktopRepositoryInitializerImpl( taskId = task.taskId, ) } + + if (task.desktopTaskTilingState == DesktopTaskTilingState.LEFT) { + repository.addLeftTiledTask( + persistentDesktop.displayId, + task.taskId, + ) + } else if ( + task.desktopTaskTilingState == DesktopTaskTilingState.RIGHT + ) { + repository.addRightTiledTask( + persistentDesktop.displayId, + task.taskId, + ) + } } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto index 010523162cec..86dcee8f8515 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto @@ -9,9 +9,16 @@ enum DesktopTaskState { MINIMIZED = 1; } +enum DesktopTaskTilingState { + NONE = 1; + LEFT = 2; + RIGHT = 3; +} + message DesktopTask { optional int32 task_id = 1; optional DesktopTaskState desktop_task_state= 2; + optional DesktopTaskTilingState desktop_task_tiling_state = 3; } message Desktop { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java index 119763ff2022..4e341ac9b7eb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java @@ -340,7 +340,8 @@ public class PipController implements ConfigurationChangeListener, mPipDisplayLayoutState.rotateTo(toRotation); } - if (!mPipTransitionState.isInPip()) { + if (!mPipTransitionState.isInPip() + && mPipTransitionState.getState() != PipTransitionState.ENTERING_PIP) { // Skip the PiP-relevant updates if we aren't in a valid PiP state. if (mPipTransitionState.isInFixedRotation()) { ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java index 294ef48c01d0..880e143a0e13 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java @@ -111,8 +111,9 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, listener.onActionsChanged(params.getActions(), params.getCloseAction()); } } - mPictureInPictureParams.copyOnlySet(params != null ? params - : new PictureInPictureParams.Builder().build()); + // Set the new params but make sure mPictureInPictureParams is not null. + mPictureInPictureParams = params == null + ? new PictureInPictureParams.Builder().build() : params; } /** Add a PipParamsChangedCallback listener. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index 9bb2e38e1526..cfcd56393bc2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -45,6 +45,7 @@ import android.app.ActivityManager; import android.app.PictureInPictureParams; import android.app.TaskInfo; import android.content.Context; +import android.graphics.Matrix; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -452,7 +453,7 @@ public class PipTransition extends PipTransitionController implements final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState); if (delta != ROTATION_0) { // Update transition target changes in place to prepare for fixed rotation. - handleBoundsEnterFixedRotation(info, pipChange, pipActivityChange); + updatePipChangesForFixedRotation(info, pipChange, pipActivityChange); } // Update the src-rect-hint in params in place, to set up initial animator transform. @@ -513,7 +514,7 @@ public class PipTransition extends PipTransitionController implements final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState); if (delta != ROTATION_0) { // Update transition target changes in place to prepare for fixed rotation. - handleBoundsEnterFixedRotation(info, pipChange, pipActivityChange); + updatePipChangesForFixedRotation(info, pipChange, pipActivityChange); } PipEnterAnimator animator = new PipEnterAnimator(mContext, pipLeash, @@ -546,7 +547,7 @@ public class PipTransition extends PipTransitionController implements return true; } - private void handleBoundsEnterFixedRotation(TransitionInfo info, + private void updatePipChangesForFixedRotation(TransitionInfo info, TransitionInfo.Change outPipTaskChange, TransitionInfo.Change outPipActivityChange) { final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info); @@ -604,10 +605,33 @@ public class PipTransition extends PipTransitionController implements SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash(); Preconditions.checkNotNull(pipLeash, "Leash is null for alpha transition."); - // Start transition with 0 alpha at the entry bounds. - startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top) - .setWindowCrop(pipLeash, destinationBounds.width(), destinationBounds.height()) - .setAlpha(pipLeash, 0f); + final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState); + if (delta != ROTATION_0) { + updatePipChangesForFixedRotation(info, pipChange, + // We don't have an activity change to animate in legacy enter, + // so just use a placeholder one as the outPipActivityChange. + new TransitionInfo.Change(null /* container */, new SurfaceControl())); + } + startTransaction.setWindowCrop(pipLeash, + destinationBounds.width(), destinationBounds.height()); + if (delta != ROTATION_0) { + // In a fixed rotation case, rotate PiP leash in the old orientation to its final + // position, but keep the bounds visually invariant until async rotation changes + // the display rotation after + int normalizedRotation = delta; + if (normalizedRotation == ROTATION_270) { + normalizedRotation = -ROTATION_90; + } + Matrix transformTensor = new Matrix(); + final float[] matrixTmp = new float[9]; + transformTensor.setTranslate(destinationBounds.left, destinationBounds.top); + transformTensor.postRotate(-normalizedRotation * 90f); + + startTransaction.setMatrix(pipLeash, transformTensor, matrixTmp); + finishTransaction.setMatrix(pipLeash, transformTensor, matrixTmp); + } else { + startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top); + } PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipLeash, startTransaction, finishTransaction, PipAlphaAnimator.FADE_IN); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt new file mode 100644 index 000000000000..d99be7104101 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2025 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.splitscreen +import android.app.ActivityManager +import android.hardware.display.DisplayManager +import android.view.SurfaceControl +import com.android.internal.protolog.ProtoLog +import com.android.wm.shell.common.split.SplitLayout +import com.android.wm.shell.protolog.ShellProtoLogGroup + +/** + * Helper class for managing split-screen functionality across multiple displays. + */ +class SplitMultiDisplayHelper(private val displayManager: DisplayManager) { + + /** + * A map that stores the [SplitTaskHierarchy] associated with each display ID. + * The keys are display IDs (integers), and the values are [SplitTaskHierarchy] objects, + * which encapsulate the information needed to manage split-screen tasks on that display. + */ + private val displayTaskMap: MutableMap<Int, SplitTaskHierarchy> = mutableMapOf() + + /** + * SplitTaskHierarchy is a class that encapsulates the components required + * for managing split-screen functionality on a specific display. + */ + data class SplitTaskHierarchy( + var rootTaskInfo: ActivityManager.RunningTaskInfo? = null, + var mainStage: StageTaskListener? = null, + var sideStage: StageTaskListener? = null, + var rootTaskLeash: SurfaceControl? = null, + var splitLayout: SplitLayout? = null + ) + + /** + * Returns a list of all currently connected display IDs. + * + * @return An ArrayList of display IDs. + */ + fun getDisplayIds(): ArrayList<Int> { + val displayIds = ArrayList<Int>() + displayManager.displays?.forEach { display -> + displayIds.add(display.displayId) + } + return displayIds + } + + /** + * Swaps the [SplitTaskHierarchy] objects associated with two different display IDs. + * + * @param firstDisplayId The ID of the first display. + * @param secondDisplayId The ID of the second display. + */ + fun swapDisplayTaskHierarchy(firstDisplayId: Int, secondDisplayId: Int) { + if (!displayTaskMap.containsKey(firstDisplayId) || !displayTaskMap.containsKey(secondDisplayId)) { + ProtoLog.w( + ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "Attempted to swap task hierarchies for invalid display IDs: %d, %d", + firstDisplayId, + secondDisplayId + ) + return + } + + if (firstDisplayId == secondDisplayId) { + return + } + + val firstHierarchy = displayTaskMap[firstDisplayId] + val secondHierarchy = displayTaskMap[secondDisplayId] + + displayTaskMap[firstDisplayId] = checkNotNull(secondHierarchy) + displayTaskMap[secondDisplayId] = checkNotNull(firstHierarchy) + } + + /** + * Gets the root task info for the given display ID. + * + * @param displayId The ID of the display. + * @return The root task info, or null if not found. + */ + fun getDisplayRootTaskInfo(displayId: Int): ActivityManager.RunningTaskInfo? { + return displayTaskMap[displayId]?.rootTaskInfo + } + + /** + * Sets the root task info for the given display ID. + * + * @param displayId The ID of the display. + * @param rootTaskInfo The root task info to set. + */ + fun setDisplayRootTaskInfo( + displayId: Int, + rootTaskInfo: ActivityManager.RunningTaskInfo? + ) { + val hierarchy = displayTaskMap.computeIfAbsent(displayId) { SplitTaskHierarchy() } + hierarchy.rootTaskInfo = rootTaskInfo + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.kt index d2e57e51762b..dce3dc1809c9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.kt @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.android.wm.shell.splitscreen; +package com.android.wm.shell.splitscreen -import android.window.WindowContainerToken; +import android.window.WindowContainerToken -public interface SplitMultiDisplayProvider { +interface SplitMultiDisplayProvider { /** * Returns the WindowContainerToken for the root of the given display ID. * * @param displayId The ID of the display. * @return The {@link WindowContainerToken} associated with the display's root task. */ - WindowContainerToken getDisplayRootForDisplayId(int displayId); + fun getDisplayRootForDisplayId(displayId: Int): WindowContainerToken? } 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 a7cba76ea91f..014c810d1e5f 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 @@ -101,6 +101,7 @@ import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.hardware.devicestate.DeviceStateManager; +import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -278,6 +279,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // because we will be posting and removing it from the handler. private final Runnable mReEnableLaunchAdjacentOnRoot = () -> setLaunchAdjacentDisabled(false); + private SplitMultiDisplayHelper mSplitMultiDisplayHelper; + /** * Since StageCoordinator only coordinates MainStage and SideStage, it shouldn't support * CompatUI layouts. CompatUI is handled separately by MainStage and SideStage. @@ -393,6 +396,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mDesktopTasksController = desktopTasksController; mRootTDAOrganizer = rootTDAOrganizer; + DisplayManager displayManager = context.getSystemService(DisplayManager.class); + + mSplitMultiDisplayHelper = new SplitMultiDisplayHelper( + Objects.requireNonNull(displayManager)); + taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */); ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Creating main/side root task"); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index f2ff39627362..800faca830f4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -1609,7 +1609,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, relevantDecor.mTaskInfo, relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY(), dragStartState); - if (indicatorType != TO_FULLSCREEN_INDICATOR) { + if (indicatorType != TO_FULLSCREEN_INDICATOR + || BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { if (mMoveToDesktopAnimator == null) { mMoveToDesktopAnimator = new MoveToDesktopAnimator( mContext, mDragToDesktopAnimationStartBounds, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 003baae29114..bcf9396ff0c1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -553,7 +553,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return; } - if (oldRootView != mResult.mRootView) { + if (DesktopModeFlags.SKIP_DECOR_VIEW_RELAYOUT_WHEN_CLOSING_BUGFIX.isTrue() + ? (oldRootView != mResult.mRootView && taskInfo.isVisibleRequested) + : oldRootView != mResult.mRootView) { disposeStatusBarInputLayer(); mWindowDecorViewHolder = createViewHolder(); // Load these only when first creating the view. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java index 7a4a834e9dc2..8a8bdcadd67a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java @@ -23,12 +23,12 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERL import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; +import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP; -import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEdgeResizePermitted; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEventFromTouchscreen; @@ -127,7 +127,9 @@ class DragResizeInputListener implements AutoCloseable { Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, DisplayController displayController, - DesktopModeEventLogger desktopModeEventLogger) { + DesktopModeEventLogger desktopModeEventLogger, + InputChannel inputChannel, + InputChannel sinkInputChannel) { mContext = context; mWindowSession = windowSession; mBgExecutor = bgExecutor; @@ -136,7 +138,11 @@ class DragResizeInputListener implements AutoCloseable { mHandler = handler; mChoreographer = choreographer; mDisplayId = displayId; - mDecorationSurface = decorationSurface; + // Creates a new SurfaceControl pointing the same underlying surface with decorationSurface + // to ensure that mDecorationSurface will not be released while it's used on the background + // thread. Note that the empty name will be overridden by the next copyFrom call. + mDecorationSurface = surfaceControlBuilderSupplier.get().setName("").build(); + mDecorationSurface.copyFrom(decorationSurface, "DragResizeInputListener"); mDragPositioningCallback = callback; mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier; mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier; @@ -154,9 +160,13 @@ class DragResizeInputListener implements AutoCloseable { final InputSetUpResult result = setUpInputChannels(mDisplayId, mWindowSession, mDecorationSurface, mClientToken, mSinkClientToken, mSurfaceControlBuilderSupplier, - mSurfaceControlTransactionSupplier); + mSurfaceControlTransactionSupplier, inputChannel, sinkInputChannel); mainExecutor.execute(() -> { if (mClosed) { + result.mInputChannel.dispose(); + result.mSinkInputChannel.dispose(); + mSurfaceControlTransactionSupplier.get().remove( + result.mInputSinkSurface).apply(); return; } mInputSinkSurface = result.mInputSinkSurface; @@ -208,7 +218,7 @@ class DragResizeInputListener implements AutoCloseable { new DefaultTaskResizeInputEventReceiverFactory(), taskInfo, handler, choreographer, displayId, decorationSurface, callback, surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, - displayController, desktopModeEventLogger); + displayController, desktopModeEventLogger, new InputChannel(), new InputChannel()); } DragResizeInputListener( @@ -251,11 +261,11 @@ class DragResizeInputListener implements AutoCloseable { @NonNull IBinder clientToken, @NonNull IBinder sinkClientToken, @NonNull Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, - @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) { + @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, + @NonNull InputChannel inputChannel, + @NonNull InputChannel sinkInputChannel) { Trace.beginSection("DragResizeInputListener#setUpInputChannels"); final InputTransferToken inputTransferToken = new InputTransferToken(); - final InputChannel inputChannel = new InputChannel(); - final InputChannel sinkInputChannel = new InputChannel(); try { windowSession.grantInputChannel( displayId, @@ -332,6 +342,7 @@ class DragResizeInputListener implements AutoCloseable { try { mWindowSession.updateInputChannel( mInputChannel.getToken(), + null /* hostInputToken */, mDisplayId, mDecorationSurface, FLAG_NOT_FOCUSABLE, @@ -373,6 +384,7 @@ class DragResizeInputListener implements AutoCloseable { try { mWindowSession.updateInputChannel( mSinkInputChannel.getToken(), + null /* hostInputToken */, mDisplayId, mInputSinkSurface, FLAG_NOT_FOCUSABLE, @@ -421,6 +433,9 @@ class DragResizeInputListener implements AutoCloseable { } catch (RemoteException e) { e.rethrowFromSystemServer(); } + // Removing this surface on the background thread to ensure that mInitInputChannels has + // already been finished. + mSurfaceControlTransactionSupplier.get().remove(mDecorationSurface).apply(); }); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt index a8a7032d0b86..9cc64ac9c276 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt @@ -109,15 +109,18 @@ class HandleMenu( get() = (DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue() && !taskInfo.isFreeform) private val pillTopMargin: Int = loadDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_pill_spacing_margin) + R.dimen.desktop_mode_handle_menu_pill_spacing_margin + ) private val menuWidth = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_width) private val menuHeight = getHandleMenuHeight() private val marginMenuTop = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_margin_top) private val marginMenuStart = loadDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_margin_start) + R.dimen.desktop_mode_handle_menu_margin_start + ) @VisibleForTesting var handleMenuViewContainer: AdditionalViewContainer? = null + @VisibleForTesting var handleMenuView: HandleMenuView? = null @@ -136,7 +139,7 @@ class HandleMenu( private val shouldShowMoreActionsPill: Boolean get() = SHOULD_SHOW_SCREENSHOT_BUTTON || shouldShowNewWindowButton || - shouldShowManageWindowsButton || shouldShowChangeAspectRatioButton + shouldShowManageWindowsButton || shouldShowChangeAspectRatioButton private var loadAppInfoJob: Job? = null @@ -240,7 +243,8 @@ class HandleMenu( val y = handleMenuPosition.y.toInt() handleMenuViewContainer = if ((!taskInfo.isFreeform && DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) - || forceShowSystemBars) { + || forceShowSystemBars + ) { AdditionalSystemViewContainer( windowManagerWrapper = windowManagerWrapper, taskId = taskInfo.taskId, @@ -251,7 +255,11 @@ class HandleMenu( flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, view = handleMenuView.rootView, - forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 }, + forciblyShownTypes = if (forceShowSystemBars) { + systemBars() + } else { + 0 + }, ignoreCutouts = Flags.showAppHandleLargeScreens() || BubbleAnythingFlagHelper.enableBubbleToFullscreen() ) @@ -369,7 +377,8 @@ class HandleMenu( inputPoint.y - globalMenuPosition.y ) if (splitScreenController.getSplitPosition(taskInfo.taskId) - == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT) { + == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT + ) { val leftStageBounds = Rect() splitScreenController.getStageBounds(leftStageBounds, Rect()) inputRelativeToMenu.x += leftStageBounds.width().toFloat() @@ -398,7 +407,8 @@ class HandleMenu( var menuHeight = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_height) if (!shouldShowWindowingPill) { menuHeight -= loadDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_windowing_pill_height) + R.dimen.desktop_mode_handle_menu_windowing_pill_height + ) menuHeight -= pillTopMargin } if (!SHOULD_SHOW_SCREENSHOT_BUTTON) { @@ -418,14 +428,16 @@ class HandleMenu( } if (!shouldShowChangeAspectRatioButton) { menuHeight -= loadDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_change_aspect_ratio_height) + R.dimen.desktop_mode_handle_menu_change_aspect_ratio_height + ) } if (!shouldShowMoreActionsPill) { menuHeight -= pillTopMargin } if (!shouldShowBrowserPill) { menuHeight -= loadDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_open_in_browser_pill_height) + R.dimen.desktop_mode_handle_menu_open_in_browser_pill_height + ) menuHeight -= pillTopMargin } return menuHeight @@ -468,48 +480,66 @@ class HandleMenu( // Insets for ripple effect of App Info Pill. and Windowing Pill. buttons val iconButtondrawableShiftInset = context.resources.getDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_shift) + R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_shift + ) val iconButtondrawableBaseInset = context.resources.getDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_base) + R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_base + ) private val iconButtonRippleRadius = context.resources.getDimensionPixelSize( - R.dimen.desktop_mode_handle_menu_icon_button_ripple_radius) - private val iconButtonDrawableInsetsBase = DrawableInsets(t = iconButtondrawableBaseInset, + R.dimen.desktop_mode_handle_menu_icon_button_ripple_radius + ) + private val iconButtonDrawableInsetsBase = DrawableInsets( + t = iconButtondrawableBaseInset, b = iconButtondrawableBaseInset, l = iconButtondrawableBaseInset, - r = iconButtondrawableBaseInset) - private val iconButtonDrawableInsetsLeft = DrawableInsets(t = iconButtondrawableBaseInset, - b = iconButtondrawableBaseInset, l = iconButtondrawableShiftInset, r = 0) - private val iconButtonDrawableInsetsRight = DrawableInsets(t = iconButtondrawableBaseInset, - b = iconButtondrawableBaseInset, l = 0, r = iconButtondrawableShiftInset) + r = iconButtondrawableBaseInset + ) + private val iconButtonDrawableInsetsLeft = DrawableInsets( + t = iconButtondrawableBaseInset, + b = iconButtondrawableBaseInset, l = iconButtondrawableShiftInset, r = 0 + ) + private val iconButtonDrawableInsetsRight = DrawableInsets( + t = iconButtondrawableBaseInset, + b = iconButtondrawableBaseInset, l = 0, r = iconButtondrawableShiftInset + ) // App Info Pill. private val appInfoPill = rootView.requireViewById<View>(R.id.app_info_pill) private val collapseMenuButton = appInfoPill.requireViewById<HandleMenuImageButton>( - R.id.collapse_menu_button) + R.id.collapse_menu_button + ) + @VisibleForTesting val appIconView = appInfoPill.requireViewById<ImageView>(R.id.application_icon) + @VisibleForTesting val appNameView = appInfoPill.requireViewById<MarqueedTextView>(R.id.application_name) // Windowing Pill. private val windowingPill = rootView.requireViewById<View>(R.id.windowing_pill) private val fullscreenBtn = windowingPill.requireViewById<ImageButton>( - R.id.fullscreen_button) + R.id.fullscreen_button + ) private val splitscreenBtn = windowingPill.requireViewById<ImageButton>( - R.id.split_screen_button) + R.id.split_screen_button + ) private val floatingBtn = windowingPill.requireViewById<ImageButton>(R.id.floating_button) private val floatingBtnSpace = windowingPill.requireViewById<Space>( - R.id.floating_button_space) + R.id.floating_button_space + ) private val desktopBtn = windowingPill.requireViewById<ImageButton>(R.id.desktop_button) private val desktopBtnSpace = windowingPill.requireViewById<Space>( - R.id.desktop_button_space) + R.id.desktop_button_space + ) // More Actions Pill. private val moreActionsPill = rootView.requireViewById<View>(R.id.more_actions_pill) private val screenshotBtn = moreActionsPill.requireViewById<HandleMenuActionButton>( - R.id.screenshot_button) + R.id.screenshot_button + ) private val newWindowBtn = moreActionsPill.requireViewById<HandleMenuActionButton>( - R.id.new_window_button) + R.id.new_window_button + ) private val manageWindowBtn = moreActionsPill .requireViewById<HandleMenuActionButton>(R.id.manage_windows_button) private val changeAspectRatioBtn = moreActionsPill @@ -517,11 +547,14 @@ class HandleMenu( // Open in Browser/App Pill. private val openInAppOrBrowserPill = rootView.requireViewById<View>( - R.id.open_in_app_or_browser_pill) + R.id.open_in_app_or_browser_pill + ) private val openInAppOrBrowserBtn = openInAppOrBrowserPill.requireViewById<View>( - R.id.open_in_app_or_browser_button) + R.id.open_in_app_or_browser_button + ) private val openByDefaultBtn = openInAppOrBrowserPill.requireViewById<ImageButton>( - R.id.open_by_default_button) + R.id.open_by_default_button + ) private val decorThemeUtil = DecorThemeUtil(context) private val animator = HandleMenuAnimator(rootView, menuWidth, captionHeight.toFloat()) @@ -730,9 +763,9 @@ class HandleMenu( desktopBtn.imageTintList = style.windowingButtonColor val startInsets = if (context.isRtl) iconButtonDrawableInsetsRight - else iconButtonDrawableInsetsLeft + else iconButtonDrawableInsetsLeft val endInsets = if (context.isRtl) iconButtonDrawableInsetsLeft - else iconButtonDrawableInsetsRight + else iconButtonDrawableInsetsRight fullscreenBtn.apply { background = createBackgroundDrawable( @@ -804,9 +837,11 @@ class HandleMenu( getString(R.string.open_in_browser_text) } + val buttonRoot = openInAppOrBrowserBtn.requireViewById<LinearLayout>(R.id.action_button) val label = openInAppOrBrowserBtn.requireViewById<MarqueedTextView>(R.id.label) val image = openInAppOrBrowserBtn.requireViewById<ImageView>(R.id.image) openInAppOrBrowserBtn.contentDescription = btnText + buttonRoot.contentDescription = btnText label.apply { text = btnText setTextColor(style.textColor) @@ -837,7 +872,7 @@ class HandleMenu( */ fun shouldShowChangeAspectRatioButton(taskInfo: RunningTaskInfo): Boolean = taskInfo.appCompatTaskInfo.eligibleForUserAspectRatioButton() && - taskInfo.windowingMode == WindowConfiguration.WINDOWING_MODE_FULLSCREEN + taskInfo.windowingMode == WindowConfiguration.WINDOWING_MODE_FULLSCREEN } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt index 4b2e473d6ec2..a723a7a4ac20 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt @@ -23,9 +23,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.widget.ImageView import android.widget.LinearLayout -import android.widget.TextView import androidx.core.content.withStyledAttributes -import androidx.core.view.isGone import com.android.wm.shell.R /** @@ -54,6 +52,7 @@ class HandleMenuActionButton @JvmOverloads constructor( context.withStyledAttributes(attrs, R.styleable.HandleMenuActionButton) { textView.text = getString(R.styleable.HandleMenuActionButton_android_text) + rootElement.contentDescription = getString(R.styleable.HandleMenuActionButton_android_text) textView.setTextColor(getColor(R.styleable.HandleMenuActionButton_android_textColor, 0)) iconView.setImageResource(getResourceId( R.styleable.HandleMenuActionButton_android_src, 0)) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt index 7c5f34f979cd..854d9e1deef1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt @@ -137,6 +137,7 @@ class DesktopTilingWindowDecoration( // Observe drag resizing to break tiling if a task is drag resized. desktopModeWindowDecoration.addDragResizeListener(this) val callback = { initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp) } + updateDesktopRepository(taskInfo.taskId, snapPosition = position) if (isTiled) { val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds) toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds, callback) @@ -159,6 +160,14 @@ class DesktopTilingWindowDecoration( return isTiled } + private fun updateDesktopRepository(taskId: Int, snapPosition: SnapPosition) { + when (snapPosition) { + SnapPosition.LEFT -> desktopUserRepositories.current.addLeftTiledTask(displayId, taskId) + SnapPosition.RIGHT -> + desktopUserRepositories.current.addRightTiledTask(displayId, taskId) + } + } + // If a task is already tiled on the same position, release this task, otherwise if the same // task is tiled on the opposite side, remove it from the opposite side so it's tiled correctly. private fun initTilingApps( @@ -580,6 +589,7 @@ class DesktopTilingWindowDecoration( ) { val taskRepository = desktopUserRepositories.current if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) { + desktopUserRepositories.current.removeLeftTiledTask(displayId) removeTask(leftTaskResizingHelper, taskVanished, shouldDelayUpdate) leftTaskResizingHelper = null val taskId = rightTaskResizingHelper?.taskInfo?.taskId @@ -593,6 +603,7 @@ class DesktopTilingWindowDecoration( } if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) { + desktopUserRepositories.current.removeRightTiledTask(displayId) removeTask(rightTaskResizingHelper, taskVanished, shouldDelayUpdate) rightTaskResizingHelper = null val taskId = leftTaskResizingHelper?.taskInfo?.taskId diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java index 25f17fe8a3c2..2de77b2132cf 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java @@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -37,6 +38,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.IBinder; @@ -47,7 +49,9 @@ import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; +import androidx.core.animation.AnimatorTestRule; import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.ShellTaskOrganizer; @@ -65,6 +69,7 @@ import com.android.wm.shell.taskview.TaskViewTransitions; import com.android.wm.shell.transition.Transitions; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -76,6 +81,8 @@ import org.mockito.MockitoAnnotations; @SmallTest public class BubbleTransitionsTest extends ShellTestCase { + @Rule public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(); + private static final int FULLSCREEN_TASK_WIDTH = 200; private static final int FULLSCREEN_TASK_HEIGHT = 100; @@ -292,23 +299,71 @@ public class BubbleTransitionsTest extends ShellTestCase { @Test public void convertDraggedBubbleToFullscreen() { ActivityManager.RunningTaskInfo taskInfo = setupBubble(); + SurfaceControl.Transaction animT = mock(SurfaceControl.Transaction.class); + BubbleTransitions.TransactionProvider transactionProvider = () -> animT; final DraggedBubbleIconToFullscreen bt = - (DraggedBubbleIconToFullscreen) mBubbleTransitions - .startDraggedBubbleIconToFullscreen(mBubble); + mBubbleTransitions.new DraggedBubbleIconToFullscreen( + mBubble, new Point(100, 50), transactionProvider); verify(mTransitions).startTransition(anyInt(), any(), eq(bt)); + SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build(); final TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0); + final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, taskLeash); + chg.setMode(TRANSIT_TO_FRONT); + chg.setTaskInfo(taskInfo); + info.addChange(chg); + info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0)); + SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); + SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); + boolean[] transitionFinished = {false}; + Transitions.TransitionFinishCallback finishCb = wct -> transitionFinished[0] = true; + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + bt.startAnimation(bt.mTransition, info, startT, finishT, finishCb); + mAnimatorTestRule.advanceTimeBy(250); + }); + verify(startT).setScale(taskLeash, 0, 0); + verify(startT).setPosition(taskLeash, 100, 50); + verify(startT).apply(); + verify(animT).setScale(taskLeash, 1, 1); + verify(animT).setPosition(taskLeash, 0, 0); + verify(animT, atLeastOnce()).apply(); + verify(animT).close(); + assertFalse(mTaskViewTransitions.hasPending()); + assertTrue(transitionFinished[0]); + } + + @Test + public void convertFloatingBubbleToFullscreen() { + final BubbleExpandedView bev = mock(BubbleExpandedView.class); + final ViewRootImpl vri = mock(ViewRootImpl.class); + when(bev.getViewRootImpl()).thenReturn(vri); + when(mBubble.getBubbleBarExpandedView()).thenReturn(null); + when(mBubble.getExpandedView()).thenReturn(bev); + + ActivityManager.RunningTaskInfo taskInfo = setupBubble(); + final BubbleTransitions.BubbleTransition bt = mBubbleTransitions.startConvertFromBubble( + mBubble, taskInfo); + final BubbleTransitions.ConvertFromBubble cfb = (BubbleTransitions.ConvertFromBubble) bt; + verify(mTransitions).startTransition(anyInt(), any(), eq(cfb)); + verify(mBubble).setPreparingTransition(eq(bt)); + assertTrue(mTaskViewTransitions.hasPending()); + + final TransitionInfo info = new TransitionInfo(TRANSIT_CHANGE, 0); final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, mock(SurfaceControl.class)); - chg.setMode(TRANSIT_TO_FRONT); + chg.setMode(TRANSIT_CHANGE); chg.setTaskInfo(taskInfo); info.addChange(chg); info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0)); SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); Transitions.TransitionFinishCallback finishCb = wct -> {}; - bt.startAnimation(bt.mTransition, info, startT, finishT, finishCb); - verify(startT).apply(); + cfb.startAnimation(cfb.mTransition, info, startT, finishT, finishCb); + + // Can really only verify that it interfaces with the taskViewTransitions queue. + // The actual functioning of this is tightly-coupled with SurfaceFlinger and renderthread + // in order to properly synchronize surface manipulation with drawing and thus can't be + // directly tested. assertFalse(mTaskViewTransitions.hasPending()); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt index fa95faee4b6e..9c45cd22db19 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt @@ -35,6 +35,7 @@ import java.util.function.Supplier import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.mock @@ -191,6 +192,7 @@ class LetterboxInputControllerTest : ShellTestCase() { fun checkUpdateSessionRegion(times: Int = 1, displayId: Int = DISPLAY_ID, region: Region) { verify(windowSession, times(times)).updateInputChannel( any(), + anyOrNull(), eq(displayId), any(), any(), diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt index 105941079095..96b826f93aae 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt @@ -33,11 +33,11 @@ import android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERN import android.view.Display import android.view.Display.DEFAULT_DISPLAY import android.view.IWindowManager +import android.view.InputDevice import android.view.WindowManager.TRANSIT_CHANGE import android.window.DisplayAreaInfo import android.window.WindowContainerTransaction import androidx.test.filters.SmallTest -import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.dx.mockito.inline.extended.ExtendedMockito.never import com.android.dx.mockito.inline.extended.StaticMockitoSession @@ -102,7 +102,9 @@ class DesktopDisplayModeControllerTest( TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FULLSCREEN).build() private val defaultTDA = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) private val wallpaperToken = MockToken().token() + private val defaultDisplay = mock<Display>() private val externalDisplay = mock<Display>() + private val mouseDevice = mock<InputDevice>() private lateinit var extendedDisplaySettingsRestoreSession: ExtendedDisplaySettingsRestoreSession @@ -118,7 +120,7 @@ class DesktopDisplayModeControllerTest( mockitoSession = mockitoSession() .strictness(Strictness.LENIENT) - .spyStatic(DesktopModeStatus::class.java) + .mockStatic(DesktopModeStatus::class.java) .startMocking() extendedDisplaySettingsRestoreSession = ExtendedDisplaySettingsRestoreSession(context.contentResolver) @@ -141,8 +143,18 @@ class DesktopDisplayModeControllerTest( runningTasks.add(fullscreenTask) whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenReturn(ArrayList(runningTasks)) whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(wallpaperToken) + whenever(displayController.getDisplay(DEFAULT_DISPLAY)).thenReturn(defaultDisplay) whenever(displayController.getDisplay(EXTERNAL_DISPLAY_ID)).thenReturn(externalDisplay) setTabletModeStatus(SwitchState.UNKNOWN) + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + defaultDisplay + ) + ).thenReturn(true) + whenever(mouseDevice.supportsSource(InputDevice.SOURCE_MOUSE)).thenReturn(true) + whenever(inputManager.getInputDevice(EXTERNAL_DEVICE_ID)).thenReturn(mouseDevice) + setMouseConnected(false) } @After @@ -200,6 +212,7 @@ class DesktopDisplayModeControllerTest( fun testTargetWindowingMode_formfactorDisabled( @TestParameter param: ExternalDisplayBasedTargetModeTestCase, @TestParameter tabletModeStatus: SwitchState, + @TestParameter hasAnyMouseDevice: Boolean, ) { whenever(mockWindowManager.getWindowingMode(anyInt())) .thenReturn(param.defaultWindowingMode) @@ -209,7 +222,14 @@ class DesktopDisplayModeControllerTest( disconnectExternalDisplay() } setTabletModeStatus(tabletModeStatus) + setMouseConnected(hasAnyMouseDevice) setExtendedMode(param.extendedDisplayEnabled) + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + defaultDisplay + ) + ).thenReturn(param.isDefaultDisplayDesktopEligible) assertThat(controller.getTargetWindowingModeForDefaultDisplay()) .isEqualTo(param.expectedWindowingMode) @@ -228,6 +248,13 @@ class DesktopDisplayModeControllerTest( } setTabletModeStatus(param.tabletModeStatus) setExtendedMode(param.extendedDisplayEnabled) + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + defaultDisplay + ) + ).thenReturn(param.isDefaultDisplayDesktopEligible) + setMouseConnected(param.hasAnyMouseDevice) assertThat(controller.getTargetWindowingModeForDefaultDisplay()) .isEqualTo(param.expectedWindowingMode) @@ -287,9 +314,12 @@ class DesktopDisplayModeControllerTest( private fun setExtendedMode(enabled: Boolean) { if (DisplayFlags.enableDisplayContentModeManagement()) { - doReturn(enabled).`when` { - DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, externalDisplay) - } + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + externalDisplay + ) + ).thenReturn(enabled) } else { Settings.Global.putInt( context.contentResolver, @@ -299,6 +329,11 @@ class DesktopDisplayModeControllerTest( } } + private fun setMouseConnected(connected: Boolean) { + whenever(inputManager.inputDeviceIds) + .thenReturn(if (connected) intArrayOf(EXTERNAL_DEVICE_ID) else intArrayOf()) + } + private class ExtendedDisplaySettingsRestoreSession( private val contentResolver: ContentResolver ) { @@ -323,6 +358,7 @@ class DesktopDisplayModeControllerTest( companion object { const val EXTERNAL_DISPLAY_ID = 100 + const val EXTERNAL_DEVICE_ID = 10 enum class SwitchState(val value: Int) { UNKNOWN(InputManager.SWITCH_STATE_UNKNOWN), @@ -334,54 +370,119 @@ class DesktopDisplayModeControllerTest( val defaultWindowingMode: Int, val hasExternalDisplay: Boolean, val extendedDisplayEnabled: Boolean, + val isDefaultDisplayDesktopEligible: Boolean, val expectedWindowingMode: Int, ) { - FREEFORM_EXTERNAL_EXTENDED( + FREEFORM_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = true, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_EXTERNAL_EXTENDED( + FULLSCREEN_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = true, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FREEFORM_NO_EXTERNAL_EXTENDED( + FREEFORM_NO_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = false, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_NO_EXTERNAL_EXTENDED( + FULLSCREEN_NO_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = false, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - FREEFORM_EXTERNAL_MIRROR( + FREEFORM_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = true, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_EXTERNAL_MIRROR( + FULLSCREEN_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = true, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - FREEFORM_NO_EXTERNAL_MIRROR( + FREEFORM_NO_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = false, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_NO_EXTERNAL_MIRROR( + FULLSCREEN_NO_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = false, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = true, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = true, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_NO_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = false, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_NO_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = false, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = true, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = true, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_NO_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = false, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_NO_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = false, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), } @@ -390,78 +491,392 @@ class DesktopDisplayModeControllerTest( val hasExternalDisplay: Boolean, val extendedDisplayEnabled: Boolean, val tabletModeStatus: SwitchState, + val isDefaultDisplayDesktopEligible: Boolean, + val hasAnyMouseDevice: Boolean, val expectedWindowingMode: Int, ) { - EXTERNAL_EXTENDED_TABLET( + EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_NO_MOUSE( hasExternalDisplay = true, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_TABLET_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_EXTENDED_TABLET( + NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_TABLET_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_TABLET_PROJECTED_NO_MOUSE( hasExternalDisplay = false, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - EXTERNAL_MIRROR_TABLET( + EXTERNAL_MIRROR_TABLET_PROJECTED_NO_MOUSE( hasExternalDisplay = true, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - NO_EXTERNAL_MIRROR_TABLET( + NO_EXTERNAL_MIRROR_TABLET_PROJECTED_NO_MOUSE( hasExternalDisplay = false, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - EXTERNAL_EXTENDED_CLAMSHELL( + EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_UNKNOWN_PROJECTED_NO_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED_NO_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + EXTERNAL_MIRROR_TABLET_NO_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_MOUSE( hasExternalDisplay = true, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_EXTENDED_CLAMSHELL( + NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_MOUSE( hasExternalDisplay = false, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - EXTERNAL_MIRROR_CLAMSHELL( + EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_MOUSE( hasExternalDisplay = true, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_MIRROR_CLAMSHELL( + NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_MOUSE( hasExternalDisplay = false, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - EXTERNAL_EXTENDED_UNKNOWN( + EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_MOUSE( hasExternalDisplay = true, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_EXTENDED_UNKNOWN( + NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + EXTERNAL_EXTENDED_TABLET_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_TABLET_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_TABLET_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_TABLET_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_MOUSE( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_MOUSE( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_MOUSE( hasExternalDisplay = false, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - EXTERNAL_MIRROR_UNKNOWN( + EXTERNAL_MIRROR_UNKNOWN_PROJECTED_MOUSE( hasExternalDisplay = true, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - NO_EXTERNAL_MIRROR_UNKNOWN( + NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED_MOUSE( hasExternalDisplay = false, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + hasAnyMouseDevice = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt index 6a99d4770728..a7ea66e17363 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt @@ -43,7 +43,8 @@ class DesktopModeMoveToDisplayTransitionHandlerTest : ShellTestCase() { @Before fun setUp() { - handler = DesktopModeMoveToDisplayTransitionHandler(StubTransaction()) + handler = + DesktopModeMoveToDisplayTransitionHandler(StubTransaction(), mock(), mock(), mock()) } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt index b859a00c6df4..652fae01c1b2 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt @@ -36,6 +36,7 @@ import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.SyncTransactionQueue +import com.android.wm.shell.shared.R as sharedR import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider import com.android.wm.shell.windowdecor.tiling.SnapEventHandler import com.google.common.truth.Truth.assertThat @@ -78,9 +79,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { @Before fun setUp() { - whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width()) - whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height()) - whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS) + setUpDisplayBoundsTablet() whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout) whenever(displayController.getDisplay(anyInt())).thenReturn(mContext.display) whenever(bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(any())) @@ -97,12 +96,36 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { ) } + private fun setUpDisplayBoundsTablet() { + whenever(displayLayout.width()).thenReturn(TABLET_DISPLAY_BOUNDS.width()) + whenever(displayLayout.height()).thenReturn(TABLET_DISPLAY_BOUNDS.height()) + whenever(displayLayout.stableInsets()).thenReturn(TABLET_STABLE_INSETS) + } + + private fun setUpDisplayBoundsFoldable() { + whenever(displayLayout.width()).thenReturn(FOLDABLE_DISPLAY_BOUNDS.width()) + whenever(displayLayout.height()).thenReturn(FOLDABLE_DISPLAY_BOUNDS.height()) + whenever(displayLayout.stableInsets()).thenReturn(FOLDABLE_STABLE_INSETS) + } + + private fun disableDesktop() { + mContext.orCreateTestableResources.addOverride( + com.android.internal.R.bool.config_canInternalDisplayHostDesktops, + false, + ) + } + + private fun setUpFoldable() { + setUpDisplayBoundsFoldable() + disableDesktop() + } + @Test fun testFullscreenRegionCalculation() { createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN) var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT) assertThat(testRegion.bounds) - .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * STABLE_INSETS.top)) + .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * TABLET_STABLE_INSETS.top)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM) testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT) @@ -113,9 +136,9 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { assertThat(testRegion.bounds) .isEqualTo( Rect( - (DISPLAY_BOUNDS.width() / 2f - toFullscreenWidth / 2f).toInt(), + (TABLET_DISPLAY_BOUNDS.width() / 2f - toFullscreenWidth / 2f).toInt(), Short.MIN_VALUE.toInt(), - (DISPLAY_BOUNDS.width() / 2f + toFullscreenWidth / 2f).toInt(), + (TABLET_DISPLAY_BOUNDS.width() / 2f + toFullscreenWidth / 2f).toInt(), transitionHeight, ) ) @@ -123,7 +146,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT) testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT) assertThat(testRegion.bounds) - .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * STABLE_INSETS.top)) + .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * TABLET_STABLE_INSETS.top)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT) testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT) @@ -142,7 +165,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600)) + assertThat(testRegion).isEqualTo(Rect(0, -50, 32, 1600)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM) testRegion = visualIndicator.calculateSplitLeftRegion( @@ -150,7 +173,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(0, transitionHeight, 32, 1600)) + assertThat(testRegion).isEqualTo(Rect(0, transitionHeight, 32, 1600)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT) testRegion = visualIndicator.calculateSplitLeftRegion( @@ -158,7 +181,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600)) + assertThat(testRegion).isEqualTo(Rect(0, -50, 32, 1600)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT) testRegion = visualIndicator.calculateSplitLeftRegion( @@ -166,7 +189,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600)) + assertThat(testRegion).isEqualTo(Rect(0, -50, 32, 1600)) } @Test @@ -180,7 +203,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600)) + assertThat(testRegion).isEqualTo(Rect(2368, -50, 2400, 1600)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM) testRegion = visualIndicator.calculateSplitRightRegion( @@ -188,7 +211,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(2368, transitionHeight, 2400, 1600)) + assertThat(testRegion).isEqualTo(Rect(2368, transitionHeight, 2400, 1600)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT) testRegion = visualIndicator.calculateSplitRightRegion( @@ -196,7 +219,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600)) + assertThat(testRegion).isEqualTo(Rect(2368, -50, 2400, 1600)) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT) testRegion = visualIndicator.calculateSplitRightRegion( @@ -204,41 +227,37 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { TRANSITION_AREA_WIDTH, CAPTION_HEIGHT, ) - assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600)) + assertThat(testRegion).isEqualTo(Rect(2368, -50, 2400, 1600)) } @Test fun testBubbleLeftRegionCalculation() { - val bubbleRegionWidth = - context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_width) - val bubbleRegionHeight = - context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_height) - val expectedRect = Rect(0, 1600 - bubbleRegionHeight, bubbleRegionWidth, 1600) + val bubbleRegionSize = + context.resources.getDimensionPixelSize(sharedR.dimen.drag_zone_bubble_tablet) + val expectedRect = Rect(0, 1600 - bubbleRegionSize, bubbleRegionSize, 1600) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN) var testRegion = visualIndicator.calculateBubbleLeftRegion(displayLayout) - assertThat(testRegion.bounds).isEqualTo(expectedRect) + assertThat(testRegion).isEqualTo(expectedRect) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT) testRegion = visualIndicator.calculateBubbleLeftRegion(displayLayout) - assertThat(testRegion.bounds).isEqualTo(expectedRect) + assertThat(testRegion).isEqualTo(expectedRect) } @Test fun testBubbleRightRegionCalculation() { - val bubbleRegionWidth = - context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_width) - val bubbleRegionHeight = - context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_height) - val expectedRect = Rect(2400 - bubbleRegionWidth, 1600 - bubbleRegionHeight, 2400, 1600) + val bubbleRegionSize = + context.resources.getDimensionPixelSize(sharedR.dimen.drag_zone_bubble_tablet) + val expectedRect = Rect(2400 - bubbleRegionSize, 1600 - bubbleRegionSize, 2400, 1600) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN) var testRegion = visualIndicator.calculateBubbleRightRegion(displayLayout) - assertThat(testRegion.bounds).isEqualTo(expectedRect) + assertThat(testRegion).isEqualTo(expectedRect) createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT) testRegion = visualIndicator.calculateBubbleRightRegion(displayLayout) - assertThat(testRegion.bounds).isEqualTo(expectedRect) + assertThat(testRegion).isEqualTo(expectedRect) } @Test @@ -264,47 +283,107 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE, ) - fun testDefaultIndicatorWithNoDesktop() { - mContext.orCreateTestableResources.addOverride( - com.android.internal.R.bool.config_canInternalDisplayHostDesktops, - false, - ) - // Fullscreen to center, no desktop indicator + fun testDefaultIndicators_bubblesEnabled() { createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN) - var result = visualIndicator.updateIndicatorType(PointF(500f, 500f)) - assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) - // Fullscreen to split - result = visualIndicator.updateIndicatorType(PointF(10000f, 500f)) + var result = visualIndicator.updateIndicatorType(PointF(10f, 1500f)) assertThat(result) - .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR) - result = visualIndicator.updateIndicatorType(PointF(-10000f, 500f)) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR) + result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f)) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR) + } + + @Test + @EnableFlags( + com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, + com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE, + ) + fun testDefaultIndicators_foldable_leftRightSplit() { + setUpFoldable() + + createVisualIndicator( + DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN, + isSmallTablet = true, + isLeftRightSplit = true, + ) + var result = visualIndicator.updateIndicatorType(foldCenter()) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR) + + result = visualIndicator.updateIndicatorType(foldLeftEdge()) assertThat(result) .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR) - // Fullscreen to bubble - result = visualIndicator.updateIndicatorType(PointF(100f, 1500f)) + + result = visualIndicator.updateIndicatorType(foldRightEdge()) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR) + + result = visualIndicator.updateIndicatorType(foldLeftBottom()) assertThat(result) .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR) - result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f)) + + result = visualIndicator.updateIndicatorType(foldRightBottom()) assertThat(result) .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR) - // Split to center, no desktop indicator - createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT) - result = visualIndicator.updateIndicatorType(PointF(500f, 500f)) - assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) - // Split to fullscreen - result = visualIndicator.updateIndicatorType(PointF(500f, 0f)) + + createVisualIndicator( + DesktopModeVisualIndicator.DragStartState.FROM_SPLIT, + isSmallTablet = true, + isLeftRightSplit = true, + ) + result = visualIndicator.updateIndicatorType(foldCenter()) assertThat(result) .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR) - // Split to bubble - result = visualIndicator.updateIndicatorType(PointF(100f, 1500f)) + + result = visualIndicator.updateIndicatorType(foldLeftBottom()) assertThat(result) .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR) - result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f)) + + result = visualIndicator.updateIndicatorType(foldRightBottom()) assertThat(result) .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR) - // Drag app to center, no desktop indicator - createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT) - result = visualIndicator.updateIndicatorType(PointF(500f, 500f)) + } + + @Test + @EnableFlags( + com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, + com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE, + ) + fun testDefaultIndicators_foldable_topBottomSplit() { + setUpFoldable() + + createVisualIndicator( + DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN, + isSmallTablet = true, + isLeftRightSplit = false, + ) + var result = visualIndicator.updateIndicatorType(foldCenter()) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR) + + result = visualIndicator.updateIndicatorType(foldLeftEdge()) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR) + + result = visualIndicator.updateIndicatorType(foldLeftBottom()) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR) + + result = visualIndicator.updateIndicatorType(foldRightBottom()) + assertThat(result) + .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR) + + createVisualIndicator( + DesktopModeVisualIndicator.DragStartState.FROM_SPLIT, + isSmallTablet = true, + isLeftRightSplit = false, + ) + // No indicator as top/bottom split apps should not be dragged + result = visualIndicator.updateIndicatorType(foldCenter()) + assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) + result = visualIndicator.updateIndicatorType(foldLeftBottom()) + assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) + result = visualIndicator.updateIndicatorType(foldRightBottom()) assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) } @@ -382,7 +461,11 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { verify(taskDisplayAreaOrganizer, never()).attachToDisplayArea(anyInt(), any()) } - private fun createVisualIndicator(dragStartState: DesktopModeVisualIndicator.DragStartState) { + private fun createVisualIndicator( + dragStartState: DesktopModeVisualIndicator.DragStartState, + isSmallTablet: Boolean = false, + isLeftRightSplit: Boolean = true, + ) { visualIndicator = DesktopModeVisualIndicator( desktopExecutor, @@ -396,20 +479,53 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() { dragStartState, bubbleBoundsProvider, snapEventHandler, + isSmallTablet, + isLeftRightSplit, ) } + private fun foldCenter(): PointF { + return PointF( + FOLDABLE_DISPLAY_BOUNDS.centerX().toFloat(), + FOLDABLE_DISPLAY_BOUNDS.centerY().toFloat(), + ) + } + + private fun foldLeftEdge(): PointF { + return PointF(0f, 50f) + } + + private fun foldRightEdge(): PointF { + return PointF(750f, 50f) + } + + private fun foldLeftBottom(): PointF { + return PointF(0f, 650f) + } + + private fun foldRightBottom(): PointF { + return PointF(750f, 650f) + } + companion object { private const val TRANSITION_AREA_WIDTH = 32 private const val CAPTION_HEIGHT = 50 - private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600) private const val NAVBAR_HEIGHT = 50 - private val STABLE_INSETS = + private val TABLET_DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600) + private val TABLET_STABLE_INSETS = + Rect( + TABLET_DISPLAY_BOUNDS.left, + TABLET_DISPLAY_BOUNDS.top + CAPTION_HEIGHT, + TABLET_DISPLAY_BOUNDS.right, + TABLET_DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, + ) + private val FOLDABLE_DISPLAY_BOUNDS = Rect(0, 0, 800, 700) + private val FOLDABLE_STABLE_INSETS = Rect( - DISPLAY_BOUNDS.left, - DISPLAY_BOUNDS.top + CAPTION_HEIGHT, - DISPLAY_BOUNDS.right, - DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, + FOLDABLE_DISPLAY_BOUNDS.left, + FOLDABLE_DISPLAY_BOUNDS.top + CAPTION_HEIGHT, + FOLDABLE_DISPLAY_BOUNDS.right, + FOLDABLE_DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT, ) } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt new file mode 100644 index 000000000000..ef394d81cc57 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2025 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.desktopmode + +import android.app.WindowConfiguration.WINDOWING_MODE_PINNED +import android.os.Binder +import android.platform.test.annotations.EnableFlags +import android.platform.test.flag.junit.SetFlagsRule +import android.testing.AndroidTestingRunner +import android.view.WindowManager.TRANSIT_PIP +import android.window.TransitionInfo +import androidx.test.filters.SmallTest +import com.android.window.flags.Flags +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.TestRunningTaskInfoBuilder +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock + +/** + * Tests for [DesktopPipTransitionObserver]. + * + * Build/Install/Run: atest WMShellUnitTests:DesktopPipTransitionObserverTest + */ +@SmallTest +@RunWith(AndroidTestingRunner::class) +class DesktopPipTransitionObserverTest : ShellTestCase() { + + @JvmField @Rule val setFlagsRule = SetFlagsRule() + + private lateinit var observer: DesktopPipTransitionObserver + + private val transition = Binder() + private var onSuccessInvokedCount = 0 + + @Before + fun setUp() { + observer = DesktopPipTransitionObserver() + + onSuccessInvokedCount = 0 + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP) + fun onTransitionReady_taskInPinnedWindowingMode_onSuccessInvoked() { + val taskId = 1 + val pipTransition = createPendingPipTransition(taskId) + val successfulChange = createChange(taskId, WINDOWING_MODE_PINNED) + observer.addPendingPipTransition(pipTransition) + + observer.onTransitionReady( + transition = transition, + info = TransitionInfo( + TRANSIT_PIP, /* flags= */ + 0 + ).apply { addChange(successfulChange) }, + ) + + assertThat(onSuccessInvokedCount).isEqualTo(1) + } + + private fun createPendingPipTransition( + taskId: Int + ): DesktopPipTransitionObserver.PendingPipTransition { + return DesktopPipTransitionObserver.PendingPipTransition( + token = transition, + taskId = taskId, + onSuccess = { onSuccessInvokedCount += 1 }, + ) + } + + private fun createChange(taskId: Int, windowingMode: Int): TransitionInfo.Change { + return TransitionInfo.Change(mock(), mock()).apply { + taskInfo = + TestRunningTaskInfoBuilder() + .setTaskId(taskId) + .setWindowingMode(windowingMode) + .build() + } + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt index c455205f6411..3fb008377d6e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt @@ -58,6 +58,7 @@ import org.mockito.Mockito.spy import org.mockito.kotlin.any import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.eq +import org.mockito.kotlin.isNull import org.mockito.kotlin.never import org.mockito.kotlin.times import org.mockito.kotlin.verify @@ -331,6 +332,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(1)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -339,6 +342,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(1, 2)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -358,6 +363,52 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { } @Test + @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE) + fun leftTiledTask_updatedInRepoAndPersisted() { + runTest(StandardTestDispatcher()) { + repo.addLeftTiledTask(displayId = DEFAULT_DISPLAY, taskId = 1) + + assertThat(repo.getLeftTiledTask(displayId = DEFAULT_DISPLAY)).isEqualTo(1) + verify(persistentRepository) + .addOrUpdateDesktop( + DEFAULT_USER_ID, + DEFAULT_DESKTOP_ID, + visibleTasks = ArraySet(), + minimizedTasks = ArraySet(), + freeformTasksInZOrder = arrayListOf(), + leftTiledTask = 1, + rightTiledTask = null, + ) + + repo.removeRightTiledTask(displayId = DEFAULT_DISPLAY) + assertThat(repo.getRightTiledTask(displayId = DEFAULT_DISPLAY)).isNull() + } + } + + @Test + @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE) + fun rightTiledTask_updatedInRepoAndPersisted() { + runTest(StandardTestDispatcher()) { + repo.addRightTiledTask(displayId = DEFAULT_DISPLAY, taskId = 1) + + assertThat(repo.getRightTiledTask(displayId = DEFAULT_DISPLAY)).isEqualTo(1) + verify(persistentRepository) + .addOrUpdateDesktop( + DEFAULT_USER_ID, + DEFAULT_DESKTOP_ID, + visibleTasks = ArraySet(), + minimizedTasks = ArraySet(), + freeformTasksInZOrder = arrayListOf(), + leftTiledTask = null, + rightTiledTask = 1, + ) + + repo.removeLeftTiledTask(displayId = DEFAULT_DISPLAY) + assertThat(repo.getLeftTiledTask(displayId = DEFAULT_DISPLAY)).isNull() + } + } + + @Test fun isOnlyVisibleNonClosingTask_singleVisibleMinimizedTask() { val taskId = 1 repo.addTask(DEFAULT_DISPLAY, taskId, isVisible = true) @@ -663,6 +714,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -671,6 +724,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(6, 5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -679,6 +734,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5, 6)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(7, 6, 5), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -729,6 +786,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -737,6 +796,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(6, 5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -745,6 +806,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5, 6)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(7, 6, 5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository, times(2)) .addOrUpdateDesktop( @@ -753,6 +816,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5, 7)), minimizedTasks = ArraySet(arrayOf(6)), freeformTasksInZOrder = arrayListOf(7, 6, 5), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -793,6 +858,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(1), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -801,6 +868,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = ArrayList(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -830,6 +899,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(1), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -838,6 +909,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = ArrayList(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -869,6 +942,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(1), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository, never()) .addOrUpdateDesktop( @@ -877,6 +952,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = ArrayList(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -1237,36 +1314,6 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { } @Test - fun setTaskInPip_savedAsMinimizedPipInDisplay() { - assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isFalse() - - repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true) - - assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isTrue() - } - - @Test - fun removeTaskInPip_removedAsMinimizedPipInDisplay() { - repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true) - assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isTrue() - - repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = false) - - assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isFalse() - } - - @Test - fun setTaskInPip_multipleDisplays_bothAreInPip() { - repo.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) - repo.setActiveDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) - repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true) - repo.setTaskInPip(SECOND_DISPLAY, taskId = 2, enterPip = true) - - assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isTrue() - assertThat(repo.isTaskMinimizedPipInDisplay(SECOND_DISPLAY, taskId = 2)).isTrue() - } - - @Test @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun addTask_deskDoesNotExists_createsDesk() { repo.addTask(displayId = 999, taskId = 6, isVisible = true) @@ -1421,6 +1468,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = any(), minimizedTasks = any(), freeformTasksInZOrder = any(), + leftTiledTask = isNull(), + rightTiledTask = isNull(), ) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index 8d8140c47c1a..71e46bcb0698 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -265,6 +265,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Mock private lateinit var desksOrganizer: DesksOrganizer @Mock private lateinit var userProfileContexts: UserProfileContexts @Mock private lateinit var desksTransitionsObserver: DesksTransitionObserver + @Mock private lateinit var desktopPipTransitionObserver: DesktopPipTransitionObserver @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var mockDisplayContext: Context @Mock private lateinit var dragToDisplayTransitionHandler: DragToDisplayTransitionHandler @@ -359,6 +360,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() .thenReturn(Binder()) whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout) whenever(displayController.getDisplayContext(anyInt())).thenReturn(mockDisplayContext) + whenever(mockDisplayContext.resources).thenReturn(resources) whenever(displayController.getDisplay(anyInt())).thenReturn(display) whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) @@ -393,6 +395,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(wallpaperToken) whenever(userProfileContexts[anyInt()]).thenReturn(context) whenever(userProfileContexts.getOrCreate(anyInt())).thenReturn(context) + whenever(freeformTaskTransitionStarter.startPipTransition(any())).thenReturn(Binder()) controller = createController() controller.setSplitScreenController(splitScreenController) @@ -457,6 +460,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() overviewToDesktopTransitionObserver, desksOrganizer, desksTransitionsObserver, + Optional.of(desktopPipTransitionObserver), userProfileContexts, desktopModeCompatPolicy, dragToDisplayTransitionHandler, @@ -3502,6 +3506,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP) fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() { val task = setUpPipTask(autoEnterEnabled = true) val handler = mock(TransitionHandler::class.java) @@ -3516,6 +3521,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP) fun onPipTaskMinimize_autoEnterDisabled_startMinimizeTransition() { val task = setUpPipTask(autoEnterEnabled = false) whenever( @@ -3535,6 +3541,103 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP) + fun onPipTaskMinimize_autoEnterEnabled_sendsTaskbarRoundingUpdate() { + val task = setUpPipTask(autoEnterEnabled = true) + val handler = mock(TransitionHandler::class.java) + whenever(transitions.dispatchRequest(any(), any(), anyOrNull())) + .thenReturn(android.util.Pair(handler, WindowContainerTransaction())) + + controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON) + + verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(anyBoolean()) + } + + @Test + @EnableFlags( + Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER, + Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP, + ) + fun onDesktopTaskEnteredPip_pipIsLastTask_removesWallpaper() { + val task = setUpPipTask(autoEnterEnabled = true) + + controller.onDesktopTaskEnteredPip( + taskId = task.taskId, + deskId = DEFAULT_DISPLAY, + displayId = task.displayId, + taskIsLastVisibleTaskBeforePip = true, + ) + + // Wallpaper is moved to the back + val wct = getLatestTransition() + wct.assertReorder(wallpaperToken, /* toTop= */ false) + } + + @Test + @EnableFlags( + Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP, + Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, + ) + fun onDesktopTaskEnteredPip_pipIsLastTask_deactivatesDesk() { + val deskId = DEFAULT_DISPLAY + val task = setUpPipTask(autoEnterEnabled = true, deskId = deskId) + val transition = Binder() + whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) + + controller.onDesktopTaskEnteredPip( + taskId = task.taskId, + deskId = deskId, + displayId = task.displayId, + taskIsLastVisibleTaskBeforePip = true, + ) + + verify(desksOrganizer).deactivateDesk(any(), eq(deskId)) + verify(desksTransitionsObserver) + .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId)) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP) + fun onDesktopTaskEnteredPip_pipIsLastTask_launchesHome() { + val task = setUpPipTask(autoEnterEnabled = true) + + controller.onDesktopTaskEnteredPip( + taskId = task.taskId, + deskId = DEFAULT_DISPLAY, + displayId = task.displayId, + taskIsLastVisibleTaskBeforePip = true, + ) + + val wct = getLatestTransition() + wct.assertPendingIntent(launchHomeIntent(DEFAULT_DISPLAY)) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP) + fun onDesktopTaskEnteredPip_pipIsNotLastTask_doesntExitDesktopMode() { + val task = setUpPipTask(autoEnterEnabled = true) + val deskId = DEFAULT_DISPLAY + setUpFreeformTask(deskId = deskId) // launch another freeform task + val transition = Binder() + whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) + + controller.onDesktopTaskEnteredPip( + taskId = task.taskId, + deskId = deskId, + displayId = task.displayId, + taskIsLastVisibleTaskBeforePip = false, + ) + + // No transition to exit Desktop mode is started + verifyWCTNotExecuted() + verify(desktopModeEnterExitTransitionListener, never()) + .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) + verify(desksOrganizer, never()).deactivateDesk(any(), eq(deskId)) + verify(desksTransitionsObserver, never()) + .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId)) + } + + @Test fun onDesktopWindowMinimize_singleActiveTask_noWallpaperActivityToken_doesntRemoveWallpaper() { val task = setUpFreeformTask(active = true) val transition = Binder() @@ -3752,6 +3855,24 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + fun onDesktopWindowMinimize_sendsTaskbarRoundingUpdate() { + val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) + val transition = Binder() + whenever( + freeformTaskTransitionStarter.startMinimizedModeTransition( + any(), + anyInt(), + anyBoolean(), + ) + ) + .thenReturn(transition) + + controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON) + + verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(anyBoolean()) + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun handleRequest_fullscreenTask_switchToDesktop_movesTaskToDesk() { taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = 5) @@ -7656,8 +7777,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() return task } - private fun setUpPipTask(autoEnterEnabled: Boolean): RunningTaskInfo = - setUpFreeformTask().apply { + private fun setUpPipTask( + autoEnterEnabled: Boolean, + displayId: Int = DEFAULT_DISPLAY, + deskId: Int = DEFAULT_DISPLAY, + ): RunningTaskInfo = + setUpFreeformTask(displayId = displayId, deskId = deskId).apply { pictureInPictureParams = PictureInPictureParams.Builder().setAutoEnterEnabled(autoEnterEnabled).build() } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt index ac9a509ac6cb..5ef1ace7873d 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt @@ -22,7 +22,6 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.content.ComponentName import android.content.Context import android.content.Intent -import android.os.Binder import android.os.IBinder import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags @@ -30,7 +29,6 @@ import android.view.Display.DEFAULT_DISPLAY import android.view.WindowManager import android.view.WindowManager.TRANSIT_CLOSE import android.view.WindowManager.TRANSIT_OPEN -import android.view.WindowManager.TRANSIT_PIP import android.view.WindowManager.TRANSIT_TO_BACK import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.IWindowContainerToken @@ -41,7 +39,6 @@ import android.window.WindowContainerTransaction import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER import com.android.modules.utils.testing.ExtendedMockitoRule import com.android.window.flags.Flags -import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP import com.android.wm.shell.MockToken import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.back.BackAnimationController @@ -51,10 +48,9 @@ import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpape import com.android.wm.shell.shared.desktopmode.DesktopModeStatus import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.Transitions -import com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP -import com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage +import java.util.Optional import org.junit.Before import org.junit.Rule import org.junit.Test @@ -90,6 +86,7 @@ class DesktopTasksTransitionObserverTest { private val userRepositories = mock<DesktopUserRepositories>() private val taskRepository = mock<DesktopRepository>() private val mixedHandler = mock<DesktopMixedTransitionHandler>() + private val pipTransitionObserver = mock<DesktopPipTransitionObserver>() private val backAnimationController = mock<BackAnimationController>() private val desktopWallpaperActivityTokenProvider = mock<DesktopWallpaperActivityTokenProvider>() @@ -114,6 +111,7 @@ class DesktopTasksTransitionObserverTest { transitions, shellTaskOrganizer, mixedHandler, + Optional.of(pipTransitionObserver), backAnimationController, desktopWallpaperActivityTokenProvider, shellInit, @@ -393,56 +391,6 @@ class DesktopTasksTransitionObserverTest { verify(desktopWallpaperActivityTokenProvider).removeToken(wallpaperTask.displayId) } - @Test - @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP) - fun pendingPipTransitionAborted_taskRepositoryOnPipAbortedInvoked() { - val task = createTaskInfo(1, WINDOWING_MODE_FREEFORM) - val pipTransition = Binder() - whenever(taskRepository.isTaskMinimizedPipInDisplay(any(), any())).thenReturn(true) - - transitionObserver.onTransitionReady( - transition = pipTransition, - info = createOpenChangeTransition(task, type = TRANSIT_PIP), - startTransaction = mock(), - finishTransaction = mock(), - ) - transitionObserver.onTransitionFinished(transition = pipTransition, aborted = true) - - verify(taskRepository).onPipAborted(task.displayId, task.taskId) - } - - @Test - @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP) - fun exitPipTransition_taskRepositoryClearTaskInPip() { - val task = createTaskInfo(1, WINDOWING_MODE_FREEFORM) - whenever(taskRepository.isTaskMinimizedPipInDisplay(any(), any())).thenReturn(true) - - transitionObserver.onTransitionReady( - transition = mock(), - info = createOpenChangeTransition(task, type = TRANSIT_EXIT_PIP), - startTransaction = mock(), - finishTransaction = mock(), - ) - - verify(taskRepository).setTaskInPip(task.displayId, task.taskId, enterPip = false) - } - - @Test - @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP) - fun removePipTransition_taskRepositoryClearTaskInPip() { - val task = createTaskInfo(1, WINDOWING_MODE_FREEFORM) - whenever(taskRepository.isTaskMinimizedPipInDisplay(any(), any())).thenReturn(true) - - transitionObserver.onTransitionReady( - transition = mock(), - info = createOpenChangeTransition(task, type = TRANSIT_REMOVE_PIP), - startTransaction = mock(), - finishTransaction = mock(), - ) - - verify(taskRepository).setTaskInPip(task.displayId, task.taskId, enterPip = false) - } - private fun createBackNavigationTransition( task: RunningTaskInfo?, type: Int = TRANSIT_TO_BACK, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt index 5f92326b5e5e..6039b8f0edc5 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt @@ -115,6 +115,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) @@ -124,6 +126,50 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { } @Test + fun addTiledTasks_addsTiledTasksToDesktop() { + runTest(StandardTestDispatcher()) { + // Create a basic repository state + val task = createDesktopTask(1) + val desktopPersistentRepositories = createRepositoryWithOneDesk(task) + testDatastore.updateData { desktopPersistentRepositories } + // Create a new state to be initialized + val visibleTasks = ArraySet(listOf(1, 2)) + + // Update with new state + datastoreRepository.addOrUpdateDesktop( + visibleTasks = visibleTasks, + minimizedTasks = ArraySet(), + freeformTasksInZOrder = ArrayList(), + userId = DEFAULT_USER_ID, + leftTiledTask = 1, + rightTiledTask = null, + ) + + var actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(1)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.LEFT) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(2)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.NONE) + + // Update with new state + datastoreRepository.addOrUpdateDesktop( + visibleTasks = visibleTasks, + minimizedTasks = ArraySet(), + freeformTasksInZOrder = ArrayList(), + userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = 2, + ) + + actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(1)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.NONE) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(2)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.RIGHT) + } + } + + @Test fun removeUsers_removesUsersData() { runTest(StandardTestDispatcher()) { val task = createDesktopTask(1) @@ -138,12 +184,16 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) datastoreRepository.addOrUpdateDesktop( visibleTasks = visibleTasks, minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = USER_ID_2, + leftTiledTask = null, + rightTiledTask = null, ) datastoreRepository.removeUsers(mutableListOf(USER_ID_2)) @@ -175,6 +225,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) @@ -200,6 +252,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java index b6894fd0a9fa..a760890c9db3 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java @@ -196,6 +196,7 @@ public class PipTaskListenerTest { verifyNoMoreInteractions(mMockPipParamsChangedCallback); verify(mMockPipTransitionState, times(0)) .setOnIdlePipTransitionStateRunnable(any(Runnable.class)); + assertTrue(mPipTaskListener.getPictureInPictureParams().empty()); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt new file mode 100644 index 000000000000..23751b69fad5 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2025 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.splitscreen + +import android.app.ActivityManager +import android.hardware.display.DisplayManager +import android.view.Display +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.common.split.SplitLayout +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.mock +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +/** + * Unit tests for [SplitMultiDisplayHelper]. + */ +@SmallTest +@RunWith(AndroidJUnit4::class) +class SplitMultiDisplayHelperTests : ShellTestCase() { + + private lateinit var splitMultiDisplayHelper: SplitMultiDisplayHelper + + @Mock + private lateinit var mockDisplayManager: DisplayManager + @Mock + private lateinit var mockSplitLayout: SplitLayout + @Mock + private lateinit var mockDisplay1: Display + @Mock + private lateinit var mockDisplay2: Display + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + mockDisplay1 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: mock(Display::class.java) + mockDisplay2 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY + 1) ?: mock(Display::class.java) + + `when`(mockDisplay1.displayId).thenReturn(Display.DEFAULT_DISPLAY) + `when`(mockDisplay2.displayId).thenReturn(Display.DEFAULT_DISPLAY + 1) + + splitMultiDisplayHelper = SplitMultiDisplayHelper(mockDisplayManager) + } + + @Test + fun getDisplayIds_noDisplays_returnsEmptyList() { + `when`(mockDisplayManager.displays).thenReturn(emptyArray()) + + val displayIds = splitMultiDisplayHelper.getDisplayIds() + + assertThat(displayIds).isEmpty() + } + + @Test + fun getDisplayIds_singleDisplay_returnsCorrectId() { + `when`(mockDisplayManager.displays).thenReturn(arrayOf(mockDisplay1)) + + val displayIds = splitMultiDisplayHelper.getDisplayIds() + + assertThat(displayIds).containsExactly(Display.DEFAULT_DISPLAY) + } + + @Test + fun getDisplayIds_multiDisplays_returnsCorrectIds() { + `when`(mockDisplayManager.displays).thenReturn(arrayOf(mockDisplay1, mockDisplay2)) + + val displayIds = splitMultiDisplayHelper.getDisplayIds() + + assertThat(displayIds).containsExactly(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY + 1) + } + + @Test + fun swapDisplayTaskHierarchy_validDisplays_swapsHierarchies() { + val rootTaskInfo1 = ActivityManager.RunningTaskInfo().apply { taskId = 1 } + val rootTaskInfo2 = ActivityManager.RunningTaskInfo().apply { taskId = 2 } + + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo1) + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1, rootTaskInfo2) + + splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY + 1) + + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)).isEqualTo(rootTaskInfo2) + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1)).isEqualTo(rootTaskInfo1) + } + + @Test + fun swapDisplayTaskHierarchy_invalidFirstDisplayId_doesNothing() { + val rootTaskInfo2 = ActivityManager.RunningTaskInfo().apply { taskId = 2 } + + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1, rootTaskInfo2) + + splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.INVALID_DISPLAY, Display.DEFAULT_DISPLAY + 1) + + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.INVALID_DISPLAY)).isNull() + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1)).isEqualTo(rootTaskInfo2) + } + + @Test + fun swapDisplayTaskHierarchy_invalidSecondDisplayId_doesNothing() { + val rootTaskInfo1 = ActivityManager.RunningTaskInfo().apply { taskId = 1 } + + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo1) + + splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.DEFAULT_DISPLAY, Display.INVALID_DISPLAY) + + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)).isEqualTo(rootTaskInfo1) + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.INVALID_DISPLAY)).isNull() + } + + @Test + fun swapDisplayTaskHierarchy_sameDisplayId_doesNothing() { + val rootTaskInfo1 = ActivityManager.RunningTaskInfo().apply { taskId = 1 } + + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo1) + + splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY) + + assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)).isEqualTo(rootTaskInfo1) + } + + @Test + fun getDisplayRootTaskInfo_validDisplayId_returnsRootTaskInfo() { + val rootTaskInfo = ActivityManager.RunningTaskInfo().apply { taskId = 123 } + + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo) + + val retrievedRootTaskInfo = splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY) + + assertThat(retrievedRootTaskInfo).isEqualTo(rootTaskInfo) + } + + @Test + fun getDisplayRootTaskInfo_invalidDisplayId_returnsNull() { + val retrievedRootTaskInfo = splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.INVALID_DISPLAY) + + assertThat(retrievedRootTaskInfo).isNull() + } + + @Test + fun setDisplayRootTaskInfo_setsRootTaskInfo() { + val rootTaskInfo = ActivityManager.RunningTaskInfo().apply { taskId = 456 } + + splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo) + val retrievedRootTaskInfo = splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY) + + assertThat(retrievedRootTaskInfo).isEqualTo(rootTaskInfo) + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java index 5dff21860ef4..077b35583e04 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java @@ -571,7 +571,8 @@ public class StageCoordinatorTests extends ShellTestCase { } @Test - @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + @DisableFlags({Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, + Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX}) public void testRequestEnterSplit_didNotEnterSplitSelect_doesNotApplyTransaction() { final WindowContainerTransaction wct = new WindowContainerTransaction(); mStageCoordinator.registerSplitSelectListener( @@ -585,7 +586,8 @@ public class StageCoordinatorTests extends ShellTestCase { } @Test - @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + @DisableFlags({Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, + Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX}) public void testRequestEnterSplit_enteredSplitSelect_appliesTransaction() { final WindowContainerTransaction wct = new WindowContainerTransaction(); mStageCoordinator.registerSplitSelectListener( diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt index 7341e098add5..360099777bde 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt @@ -40,11 +40,13 @@ import com.android.wm.shell.windowdecor.DragResizeInputListener.TaskResizeInputE import com.google.common.truth.Truth.assertThat import java.util.function.Consumer import java.util.function.Supplier +import org.junit.After import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.argThat import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify @@ -63,6 +65,15 @@ class DragResizeInputListenerTest : ShellTestCase() { private val testBgExecutor = TestShellExecutor() private val mockWindowSession = mock<IWindowSession>() private val mockInputEventReceiver = mock<TaskResizeInputEventReceiver>() + private val inputChannel = mock<InputChannel>() + private val sinkInputChannel = mock<InputChannel>() + private val decorationSurface = SurfaceControl.Builder().setName("decoration surface").build() + private val createdSurfaces = ArrayList<SurfaceControl>() + + @After + fun tearDown() { + decorationSurface.release() + } @Test fun testGrantInputChannelOffMainThread() { @@ -73,6 +84,35 @@ class DragResizeInputListenerTest : ShellTestCase() { } @Test + fun testGrantInputChannelAfterDecorSurfaceReleased() { + // Keep tracking the underlying surface that the decorationSurface points to. + val forVerification = SurfaceControl(decorationSurface, "forVerification") + try { + create() + decorationSurface.release() + testBgExecutor.flushAll() + + verify(mockWindowSession) + .grantInputChannel( + anyInt(), + argThat<SurfaceControl> { isValid && isSameSurface(forVerification) }, + any(), + anyOrNull(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyOrNull(), + any(), + any(), + any(), + ) + } finally { + forVerification.release() + } + } + + @Test fun testInitializationCallback_waitsForBgSetup() { val inputListener = create() @@ -143,6 +183,40 @@ class DragResizeInputListenerTest : ShellTestCase() { verify(mockWindowSession).remove(inputListener.mSinkClientToken) } + @Test + fun testClose_afterBgSetup_disposesOfInputChannels() { + val inputListener = create() + testBgExecutor.flushAll() + inputListener.close() + testMainExecutor.flushAll() + verify(inputChannel).dispose() + verify(sinkInputChannel).dispose() + } + + @Test + fun testClose_beforeBgSetup_releaseSurfaces() { + val inputListener = create() + inputListener.close() + testBgExecutor.flushAll() + testMainExecutor.flushAll() + + assertThat(createdSurfaces).hasSize(1) + assertThat(createdSurfaces[0].isValid).isFalse() + } + + @Test + fun testClose_afterBgSetup_releaseSurfaces() { + val inputListener = create() + testBgExecutor.flushAll() + inputListener.close() + testMainExecutor.flushAll() + testBgExecutor.flushAll() + + assertThat(createdSurfaces).hasSize(2) + assertThat(createdSurfaces[0].isValid).isFalse() + assertThat(createdSurfaces[1].isValid).isFalse() + } + private fun verifyNoInputChannelGrantRequests() { verify(mockWindowSession, never()) .grantInputChannel( @@ -172,12 +246,26 @@ class DragResizeInputListenerTest : ShellTestCase() { TestHandler(Looper.getMainLooper()), mock<Choreographer>(), Display.DEFAULT_DISPLAY, - mock<SurfaceControl>(), + decorationSurface, mock<DragPositioningCallback>(), - { SurfaceControl.Builder() }, - { StubTransaction() }, + { + object : SurfaceControl.Builder() { + override fun build(): SurfaceControl { + return super.build().also { createdSurfaces.add(it) } + } + } + }, + { + object : StubTransaction() { + override fun remove(sc: SurfaceControl): SurfaceControl.Transaction { + return super.remove(sc).also { sc.release() } + } + } + }, mock<DisplayController>(), mock<DesktopModeEventLogger>(), + inputChannel, + sinkInputChannel, ) private class TestInitializationCallback : Runnable { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt index 646ec21cab9b..9e148e57260b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt @@ -28,6 +28,7 @@ import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.desktopmode.DesktopModeEventLogger +import com.android.wm.shell.desktopmode.DesktopRepository import com.android.wm.shell.desktopmode.DesktopTasksController import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask import com.android.wm.shell.desktopmode.DesktopUserRepositories @@ -63,6 +64,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() { private val transitionsMock: Transitions = mock() private val shellTaskOrganizerMock: ShellTaskOrganizer = mock() private val userRepositories: DesktopUserRepositories = mock() + private val desktopRepository: DesktopRepository = mock() private val desktopModeEventLogger: DesktopModeEventLogger = mock() private val toggleResizeDesktopTaskTransitionHandlerMock: ToggleResizeDesktopTaskTransitionHandler = @@ -105,6 +107,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() { whenever(contextMock.createContextAsUser(any(), any())).thenReturn(context) whenever(contextMock.resources).thenReturn(resourcesMock) whenever(resourcesMock.getDimensionPixelSize(any())).thenReturn(10) + whenever(userRepositories.current).thenReturn(desktopRepository) } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt index e4424f3c57f2..e5f8d7d34a47 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt @@ -653,6 +653,64 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() { verify(context, never()).getApplicationContext() } + @Test + fun addLeftTiledTask_updatesTaskRepository_whenLeftTileInitializedOrBroken() { + val task1 = createVisibleTask() + val stableBounds = STABLE_BOUNDS_MOCK + whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout) + whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> + (i.arguments.first() as Rect).set(stableBounds) + } + whenever(context.resources).thenReturn(resources) + whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width) + whenever(tiledTaskHelper.taskInfo).thenReturn(task1) + whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration) + + tilingDecoration.onAppTiled( + task1, + desktopWindowDecoration, + DesktopTasksController.SnapPosition.LEFT, + BOUNDS, + ) + + verify(desktopRepository, times(1)).addLeftTiledTask(displayId, task1.taskId) + verify(desktopRepository, never()).addRightTiledTask(displayId, task1.taskId) + + tilingDecoration.removeTaskIfTiled(task1.taskId) + + verify(desktopRepository, times(1)).removeLeftTiledTask(displayId) + verify(desktopRepository, never()).removeRightTiledTask(displayId) + } + + @Test + fun addRightTiledTask_updatesTaskRepository_whenRightTileInitializedOrBroken() { + val task1 = createVisibleTask() + val stableBounds = STABLE_BOUNDS_MOCK + whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout) + whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> + (i.arguments.first() as Rect).set(stableBounds) + } + whenever(context.resources).thenReturn(resources) + whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width) + whenever(tiledTaskHelper.taskInfo).thenReturn(task1) + whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration) + + tilingDecoration.onAppTiled( + task1, + desktopWindowDecoration, + DesktopTasksController.SnapPosition.RIGHT, + BOUNDS, + ) + + verify(desktopRepository, times(1)).addRightTiledTask(displayId, task1.taskId) + verify(desktopRepository, never()).addLeftTiledTask(displayId, task1.taskId) + + tilingDecoration.removeTaskIfTiled(task1.taskId) + + verify(desktopRepository, times(1)).removeRightTiledTask(displayId) + verify(desktopRepository, never()).removeLeftTiledTask(displayId) + } + private fun initTiledTaskHelperMock(taskInfo: ActivityManager.RunningTaskInfo) { whenever(tiledTaskHelper.bounds).thenReturn(BOUNDS) whenever(tiledTaskHelper.taskInfo).thenReturn(taskInfo) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt new file mode 100644 index 000000000000..bc4865a07f7f --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2025 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.windowdecor.viewholder + +import android.app.ActivityManager.RunningTaskInfo +import android.graphics.Point +import android.os.Handler +import android.testing.AndroidTestingRunner +import android.view.View +import android.widget.ImageButton +import androidx.test.filters.SmallTest +import com.android.internal.policy.SystemBarUtils +import com.android.wm.shell.R +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.windowdecor.WindowManagerWrapper +import org.junit.Before +import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import kotlin.test.Test + +/** + * Tests for [AppHandleViewHolder]. + * + * Build/Install/Run: + * atest WMShellUnitTests:AppHandleViewHolderTest + */ +@SmallTest +@RunWith(AndroidTestingRunner::class) +class AppHandleViewHolderTest : ShellTestCase() { + + companion object { + private const val CAPTION_WIDTH = 500 + private const val CAPTION_HEIGHT = 100 + } + + private val mockView = mock<View>() + private val mockImageButton = mock<ImageButton>() + private val mockOnTouchListener = mock<View.OnTouchListener>() + private val mockOnClickListener = mock<View.OnClickListener>() + private val mockWindowManagerWrapper = mock<WindowManagerWrapper>() + private val mockHandler = mock<Handler>() + private val mockTaskInfo = mock<RunningTaskInfo>() + + @Before + fun setup() { + whenever(mockView.context).thenReturn(mContext) + whenever(mockView.requireViewById<View>(R.id.desktop_mode_caption)) + .thenReturn(mockView) + whenever(mockView.requireViewById<ImageButton>(R.id.caption_handle)) + .thenReturn(mockImageButton) + } + + @Test + fun statusBarInputLayer_disposedWhenCaptionBelowStatusBar() { + val appHandleViewHolder: AppHandleViewHolder = spy(createAppHandleViewHolder()) + val captionPosition = Point(0, SystemBarUtils.getStatusBarHeight(mContext) + 10) + + appHandleViewHolder.bindData( + AppHandleViewHolder.HandleData( + taskInfo = mockTaskInfo, + position = captionPosition, + width = CAPTION_WIDTH, + height = CAPTION_HEIGHT, + showInputLayer = false + ) + ) + + verify(appHandleViewHolder).disposeStatusBarInputLayer() + } + + private fun createAppHandleViewHolder(): AppHandleViewHolder { + return AppHandleViewHolder( + mockView, + mockOnTouchListener, + mockOnClickListener, + mockWindowManagerWrapper, + mockHandler + ) + } +} diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp index 5a4cff0c319e..4e820b6857a1 100644 --- a/libs/androidfw/Asset.cpp +++ b/libs/androidfw/Asset.cpp @@ -453,7 +453,7 @@ status_t _FileAsset::openChunk(incfs::IncFsFileMap&& dataMap, base::unique_fd fd { assert(mFp == NULL); // no reopen assert(!mMap.has_value()); - assert(dataMap != NULL); + assert(dataMap.data()); mMap = std::move(dataMap); mStart = -1; // not used @@ -798,7 +798,7 @@ status_t _CompressedAsset::openChunk(incfs::IncFsFileMap&& dataMap, size_t uncom { assert(mFd < 0); // no re-open assert(!mMap.has_value()); - assert(dataMap != NULL); + assert(dataMap.data()); mMap = std::move(dataMap); mStart = -1; // not used diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index dc669a5eca73..aa8cbd1f0703 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -175,6 +175,8 @@ bool SkiaPipeline::setupMultiFrameCapture() { if (stream->isValid()) { mOpenMultiPicStream = std::move(stream); mSerialContext.reset(new SkSharingSerialContext()); + // passing the GrDirectContext to the SerialContext allows us to raster/serialize GPU images + mSerialContext->setDirectContext(mRenderThread.getGrContext()); SkSerialProcs procs; procs.fImageProc = SkSharingSerialContext::serializeImage; procs.fImageCtx = mSerialContext.get(); diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig index f8eb41826c6f..f26e72fa79f1 100644 --- a/location/java/android/location/flags/location.aconfig +++ b/location/java/android/location/flags/location.aconfig @@ -167,6 +167,7 @@ flag { namespace: "location" description: "Flag for GNSS assistance interface" bug: "209078566" + is_exported: true } flag { @@ -186,3 +187,21 @@ flag { bug: "398254728" is_fixed_read_only: true } + +flag { + name: "limit_fused_gps" + namespace: "location" + description: "Limits when GPS can be used for fused location requests" + bug: "401885179" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "gnss_assistance_interface_jni" + namespace: "location" + description: "Flag for GNSS assistance interface JNI" + bug: "209078566" +} + diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig index 48e2f4e15238..c9ec31bab048 100644 --- a/media/java/android/media/flags/media_better_together.aconfig +++ b/media/java/android/media/flags/media_better_together.aconfig @@ -163,6 +163,13 @@ flag { } flag { + name: "enable_output_switcher_redesign" + namespace: "media_better_together" + description: "Enables visual update for the Media Output Switcher" + bug: "388296370" +} + +flag { name: "enable_prevention_of_keep_alive_route_providers" namespace: "media_solutions" description: "Enables mechanisms to prevent route providers from keeping malicious apps alive." diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml index 1c7f1f364764..c133b7726e70 100644 --- a/packages/CompanionDeviceManager/res/values-eu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -51,10 +51,8 @@ <string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string> <string name="consent_cancel" msgid="5655005528379285841">"Utzi"</string> <string name="consent_back" msgid="2560683030046918882">"Atzera"</string> - <!-- no translation found for downward_arrow_action (2327165938832076333) --> - <skip /> - <!-- no translation found for downward_arrow (2292427714411156088) --> - <skip /> + <string name="downward_arrow_action" msgid="2327165938832076333">"Egin behera zerrendan"</string> + <string name="downward_arrow" msgid="2292427714411156088">"Beheranzko gezia"</string> <string name="permission_expand" msgid="893185038020887411">"Zabaldu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string> <string name="permission_collapse" msgid="3320833884220844084">"Tolestu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string> <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"<strong><xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g></strong> gailuan dituzten baimen berberak eman nahi dizkiezu <strong><xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g></strong> gailuko aplikazioei?"</string> diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml index 1e299b72ffb6..cf65bc9daca8 100644 --- a/packages/CompanionDeviceManager/res/values-iw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -19,7 +19,7 @@ <string name="app_label" msgid="4470785958457506021">"ניהול מכשיר מותאם"</string> <string name="confirmation_title" msgid="2244241995958340998">"לאפשר לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת אל <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="message_discovery_soft_timeout" msgid="473346859407859161">"צריך לוודא שה-<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> מופעל ב<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>, ושה<xliff:g id="PROFILE_NAME">%3$s</xliff:g> בקרבת מקום."</string> - <string name="message_discovery_hard_timeout" msgid="677514663495711424">"לא נמצאו מכשירים. אפשר לנסות שוב מאוחר יותר."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"לא נמצאו מכשירים. כדאי לנסות שוב עוד מעט."</string> <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> <string name="discovery_mixed" msgid="7071466134150760127">"חיבור Wi-Fi ו-Bluetooth"</string> diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml index 2503826b9074..6697a153187e 100644 --- a/packages/CompanionDeviceManager/res/values-ta/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml @@ -18,7 +18,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்தை அணுக <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவா?"</string> - <string name="message_discovery_soft_timeout" msgid="473346859407859161">"இந்த <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> சாதனத்தின் <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ஆன் செய்யப்பட்டு, அதன் அருகில் உங்கள் <xliff:g id="PROFILE_NAME">%3$s</xliff:g> இருப்பதை உறுதிசெய்துகொள்ளவும்."</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"இந்த <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ஆக இருக்க வேண்டும். உங்கள் <xliff:g id="PROFILE_NAME">%3$s</xliff:g> அருகில் இருக்க வேண்டும்."</string> <string name="message_discovery_hard_timeout" msgid="677514663495711424">"சாதனங்கள் எதுவும் கண்டறியப்படவில்லை. பிறகு முயலவும்."</string> <string name="discovery_bluetooth" msgid="5693557668470016164">"புளூடூத்"</string> <string name="discovery_wifi" msgid="1551782459721758773">"வைஃபை"</string> diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml index 01fc767868d4..7f2671c96f5d 100644 --- a/packages/CompanionDeviceManager/res/values-tr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -45,7 +45,7 @@ <string name="title_sensor_device_streaming" msgid="2395553261097861497">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ve <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> cihazları arasında ses ve sistem özelliklerini aktarmasına izin verilsin mi?"</string> <string name="summary_sensor_device_streaming" msgid="3413105061195145547">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> uygulaması; <xliff:g id="DEVICE_NAME_1">%3$s</xliff:g> cihazınızda oynatılan her şeye erişebilecek.<br/><br/><xliff:g id="APP_NAME_2">%1$s</xliff:g> uygulaması bu iznin erişimini kaldırana kadar sesleri <xliff:g id="DEVICE_NAME_3">%3$s</xliff:g> cihazına aktarabilecek."</string> <string name="helper_summary_sensor_device_streaming" msgid="8860174545653786353">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması, <xliff:g id="DEVICE_NAME">%2$s</xliff:g> için cihazlarınız arasında ses ve sistem özelliklerini aktarma izni istiyor."</string> - <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string> + <string name="profile_name_generic" msgid="6851028682723034988">"Cihaz"</string> <string name="summary_generic" msgid="1761976003668044801">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve seçili cihaz arasında senkronize edebilir"</string> <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string> <string name="consent_no" msgid="2640796915611404382">"İzin verme"</string> diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java index 8e52a00fe545..a0e008c9437f 100644 --- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java +++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java @@ -19,6 +19,7 @@ package com.android.location.fused; import static android.content.Intent.ACTION_USER_SWITCHED; import static android.location.LocationManager.GPS_PROVIDER; import static android.location.LocationManager.NETWORK_PROVIDER; +import static android.location.LocationRequest.QUALITY_HIGH_ACCURACY; import static android.location.LocationRequest.QUALITY_LOW_POWER; import static android.location.provider.ProviderProperties.ACCURACY_FINE; import static android.location.provider.ProviderProperties.POWER_USAGE_LOW; @@ -34,6 +35,7 @@ import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationRequest; +import android.location.flags.Flags; import android.location.provider.LocationProviderBase; import android.location.provider.ProviderProperties; import android.location.provider.ProviderRequest; @@ -61,6 +63,9 @@ public class FusedLocationProvider extends LocationProviderBase { .build(); private static final long MAX_LOCATION_COMPARISON_NS = 11 * 1000000000L; // 11 seconds + // Maximum request interval at which we will activate GPS (because GPS sometimes consumes + // excessive power with large intervals). + private static final long MAX_GPS_INTERVAL_MS = 5 * 1000; // 5 seconds private final Object mLock = new Object(); @@ -165,8 +170,13 @@ public class FusedLocationProvider extends LocationProviderBase { mNlpPresent = mLocationManager.hasProvider(NETWORK_PROVIDER); } + boolean requestAllowsGps = + Flags.limitFusedGps() + ? mRequest.getQuality() == QUALITY_HIGH_ACCURACY + && mRequest.getIntervalMillis() <= MAX_GPS_INTERVAL_MS + : !mNlpPresent || mRequest.getQuality() < QUALITY_LOW_POWER; long gpsInterval = - mGpsPresent && (!mNlpPresent || mRequest.getQuality() < QUALITY_LOW_POWER) + mGpsPresent && requestAllowsGps ? mRequest.getIntervalMillis() : INTERVAL_DISABLED; long networkInterval = mNlpPresent ? mRequest.getIntervalMillis() : INTERVAL_DISABLED; diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING index 50331014f926..716845c5b985 100644 --- a/packages/PackageInstaller/TEST_MAPPING +++ b/packages/PackageInstaller/TEST_MAPPING @@ -23,6 +23,28 @@ ] }, { + "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { + "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { "name": "CtsPackageInstallerCUJMultiUsersTestCases", "options":[ { @@ -120,6 +142,28 @@ ] }, { + "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { + "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases", + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { "name": "CtsPackageInstallerCUJMultiUsersTestCases", "options":[ { diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java index ddd9d2acdab3..9d4c5c2735fc 100644 --- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java +++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java @@ -112,6 +112,22 @@ public class MainSwitchBar extends LinearLayout implements OnCheckedChangeListen if (mSwitch.getVisibility() == VISIBLE) { mSwitch.setOnCheckedChangeListener(this); } + + if (attrs != null) { + final TypedArray a = context.obtainStyledAttributes(attrs, + androidx.preference.R.styleable.Preference, 0 /*defStyleAttr*/, + 0 /*defStyleRes*/); + final CharSequence title = a.getText( + androidx.preference.R.styleable.Preference_android_title); + setTitle(title); + //TODO(b/369470034): update to next version + if (isExpressive && Build.VERSION.SDK_INT >= VERSION_CODES.VANILLA_ICE_CREAM) { + CharSequence summary = a.getText( + androidx.preference.R.styleable.Preference_android_summary); + setSummary(summary); + } + a.recycle(); + } } @Override diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml index 686c1488fb62..112a69bb47ec 100644 --- a/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml +++ b/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml @@ -262,4 +262,30 @@ <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> </style> + + <style name="SettingsLibEntityHeaderContent"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_centerHorizontal">true</item> + <item name="android:orientation">vertical</item> + <item name="android:gravity">center_horizontal</item> + </style> + + <style name="SettingsLibEntityHeaderIcon"> + <item name="android:layout_width">@dimen/settingslib_expressive_space_large3</item> + <item name="android:layout_height">@dimen/settingslib_expressive_space_large3</item> + <item name="android:scaleType">fitCenter</item> + <item name="android:antialias">true</item> + </style> + + <style name="SettingsLibEntityHeaderTitle"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_marginTop">@dimen/settingslib_expressive_space_small1</item> + <item name="android:singleLine">false</item> + <item name="android:gravity">center</item> + <item name="android:ellipsize">marquee</item> + <item name="android:textDirection">locale</item> + <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleLarge.Emphasized</item> + </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java b/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java index fe8e8b6f1d46..6d02c5d48715 100644 --- a/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java +++ b/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java @@ -16,6 +16,8 @@ package com.android.settingslib.widget; +import static android.view.HapticFeedbackConstants.CLOCK_TICK; + import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; @@ -46,6 +48,9 @@ import com.google.android.material.slider.Slider; */ public class SliderPreference extends Preference { private static final String TAG = "SliderPreference"; + public static final int HAPTIC_FEEDBACK_MODE_NONE = 0; + public static final int HAPTIC_FEEDBACK_MODE_ON_TICKS = 1; + public static final int HAPTIC_FEEDBACK_MODE_ON_ENDS = 2; private final int mTextStartId; private final int mTextEndId; @@ -71,6 +76,8 @@ public class SliderPreference extends Preference { private int mMin; private int mMax; private int mSliderIncrement; + private int mHapticFeedbackMode = HAPTIC_FEEDBACK_MODE_NONE; + private boolean mTickVisible = false; private boolean mAdjustable; private boolean mTrackingTouch; private CharSequence mSliderContentDescription; @@ -265,6 +272,7 @@ public class SliderPreference extends Preference { } if (mSliderIncrement != 0) { mSlider.setStepSize(mSliderIncrement); + mSlider.setTickVisible(mTickVisible); } else { mSliderIncrement = (int) (mSlider.getStepSize()); } @@ -442,6 +450,29 @@ public class SliderPreference extends Preference { } /** + * Sets the haptic feedback mode. HAPTIC_FEEDBACK_MODE_ON_TICKS means to perform haptic feedback + * as the {@link Slider} value is updated; HAPTIC_FEEDBACK_MODE_ON_ENDS means to perform haptic + * feedback as the {@link Slider} value is equal to the min/max value. + * + * @param hapticFeedbackMode The haptic feedback mode. + */ + public void setHapticFeedbackMode(int hapticFeedbackMode) { + mHapticFeedbackMode = hapticFeedbackMode; + } + + /** + * Sets whether the tick marks are visible. Only used when the slider is in discrete mode. + * + * @param tickVisible The visibility of tick marks. + */ + public void setTickVisible(boolean tickVisible) { + if (tickVisible != mTickVisible) { + mTickVisible = tickVisible; + notifyChanged(); + } + } + + /** * Gets whether the current {@link Slider} value is displayed to the user. * * @return Whether the current {@link Slider} value is displayed to the user @@ -519,7 +550,16 @@ public class SliderPreference extends Preference { if (sliderValue != mSliderValue) { if (callChangeListener(sliderValue)) { setValueInternal(sliderValue, false); - // TODO: mHapticFeedbackMode + switch (mHapticFeedbackMode) { + case HAPTIC_FEEDBACK_MODE_ON_TICKS: + slider.performHapticFeedback(CLOCK_TICK); + break; + case HAPTIC_FEEDBACK_MODE_ON_ENDS: + if (mSliderValue == mMax || mSliderValue == mMin) { + slider.performHapticFeedback(CLOCK_TICK); + } + break; + } } else { slider.setValue(mSliderValue); } diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 0d31c2eb0b96..1344a25672d2 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"يتحكّم فيه إعداد محظور"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"غير متاح أثناء المكالمات"</string> <string name="disabled" msgid="8017887509554714950">"غير مفعّل"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"مفعّلة"</string> <string name="external_source_trusted" msgid="1146522036773132905">"تطبيق مسموح به"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"تطبيق غير مسموح به"</string> <string name="install_other_apps" msgid="3232595082023199454">"تثبيت التطبيقات غير المعروفة"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index b7dcfb857902..878d8972e9a8 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Məhdudlaşdırılmış Ayar ilə nəzarət edilir"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Zənglər zamanı əlçatan deyil"</string> <string name="disabled" msgid="8017887509554714950">"Deaktiv"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Aktiv"</string> <string name="external_source_trusted" msgid="1146522036773132905">"İcazə verilib"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"İcazə verilməyib"</string> <string name="install_other_apps" msgid="3232595082023199454">"Tanınmayan tətbiqlərin quraşdırılması"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 9fc0dea9abea..f49b1d2b5adc 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Управлява се чрез ограничена настройка"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Заето по време на обаждания"</string> <string name="disabled" msgid="8017887509554714950">"Деактивирано"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Активирано"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Има разрешение"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Няма разрешение"</string> <string name="install_other_apps" msgid="3232595082023199454">"Инст. на неизвестни прилож."</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 224ad41a5ad2..0e83356e185f 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Función controlada por configuración restringida"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"No disponible durante llamadas"</string> <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Habilitada"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Con permiso"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"No permitida"</string> <string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconocidas"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index d42a7a0acb3c..483e76ab4369 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"با تنظیم «حالت محدود» کنترل میشود"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"درطول تماس دردسترس نیست"</string> <string name="disabled" msgid="8017887509554714950">"غیر فعال شد"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"فعال"</string> <string name="external_source_trusted" msgid="1146522036773132905">"مجاز بودن"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"مجاز نبودن"</string> <string name="install_other_apps" msgid="3232595082023199454">"نصب برنامههای ناشناس"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index a66c8cf375a5..f6af16e74ecb 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -543,7 +543,7 @@ <skip /> <string name="external_source_trusted" msgid="1146522036773132905">"Sallittu"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Ei sallittu"</string> - <string name="install_other_apps" msgid="3232595082023199454">"Tuntemattomien sovellusten asentaminen"</string> + <string name="install_other_apps" msgid="3232595082023199454">"Asenna tuntemattomia sovelluksia"</string> <string name="home" msgid="973834627243661438">"Asetusten etusivu"</string> <string-array name="battery_labels"> <item msgid="7878690469765357158">"0 %"</item> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index f332208d742a..a5b212b432cb 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponible pendant les appels"</string> <string name="disabled" msgid="8017887509554714950">"Désactivée"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Activé"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Autorisée"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Non autorisée"</string> <string name="install_other_apps" msgid="3232595082023199454">"Installer les applis inconnues"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index b7a6abc2dfcd..352b6082081a 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -610,9 +610,9 @@ <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string> <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string> <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string> - <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string> - <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analóxica"</string> - <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string> + <string name="media_transfer_digital_line_name" msgid="312091711951124301">"Conexión S/PDIF"</string> + <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Conexión analóxica"</string> + <string name="media_transfer_aux_line_name" msgid="894135835967856689">"Conexión AUX"</string> <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Non se pode reproducir contido neste dispositivo"</string> <string name="media_output_status_require_premium" msgid="8411255800047014822">"Cambia a conta a un plan superior para facer a modificación"</string> <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Non se poden reproducir as descargas neste dispositivo"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index f2b22679b1bb..eedd262af0f4 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Կառավարվում է սահմանափակ ռեժիմի կարգավորումներով"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Զանգի ընթացքում հասանելի չէ"</string> <string name="disabled" msgid="8017887509554714950">"Կասեցված է"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Միացված է"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Թույլատրված է"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Արգելված"</string> <string name="install_other_apps" msgid="3232595082023199454">"Անհայտ հավելվածների տեղադրում"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 79438fa1fa2d..adf5b71a7ea3 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"制限付き設定によって管理されています"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通話中は利用できません"</string> <string name="disabled" msgid="8017887509554714950">"無効"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"有効"</string> <string name="external_source_trusted" msgid="1146522036773132905">"許可"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"許可しない"</string> <string name="install_other_apps" msgid="3232595082023199454">"不明なアプリのインストール"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index ea01938d93d9..e9368aa05904 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"კონტროლდება შეზღუდული რეჟიმის პარამეტრით"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"მიუწვდომელია ზარების განხორციელებისას"</string> <string name="disabled" msgid="8017887509554714950">"გამორთული"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"ჩართულია"</string> <string name="external_source_trusted" msgid="1146522036773132905">"დაშვებულია"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"დაუშვებელია"</string> <string name="install_other_apps" msgid="3232595082023199454">"უცნობი აპების ინსტალაცია"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index de93ee94271f..b183dc926c2d 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"គ្រប់គ្រងដោយការកំណត់ដែលបានរឹតបន្តឹង"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"មិនអាចប្រើបានទេអំឡុងពេលហៅទូរសព្ទ"</string> <string name="disabled" msgid="8017887509554714950">"បិទ"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"បានបើក"</string> <string name="external_source_trusted" msgid="1146522036773132905">"បានអនុញ្ញាត"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"មិនបានអនុញ្ញាត"</string> <string name="install_other_apps" msgid="3232595082023199454">"ដំឡើងកម្មវិធីដែលមិនស្គាល់"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 4c4ea64ea52f..a4e01d96761a 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ನಿರ್ಬಂಧಿಸಲಾದ ಸೆಟ್ಟಿಂಗ್ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗುತ್ತದೆ"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ಕರೆಗಳ ಸಮಯದಲ್ಲಿ ಲಭ್ಯವಿಲ್ಲ"</string> <string name="disabled" msgid="8017887509554714950">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="external_source_trusted" msgid="1146522036773132905">"ಅನುಮತಿಸಲಾಗಿದೆ"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"ಅನುಮತಿ ಇಲ್ಲ"</string> <string name="install_other_apps" msgid="3232595082023199454">"ಅಪರಿಚಿತ ಆ್ಯಪ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index f57ed0cea03b..ebba474c243e 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ຄວບຄຸມໂດຍການຕັ້ງຄ່າທີ່ຈຳກັດໄວ້"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ບໍ່ສາມາດໃຊ້ໄດ້ລະຫວ່າງການໂທ"</string> <string name="disabled" msgid="8017887509554714950">"ປິດການນຳໃຊ້"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"ເປີດການນຳໃຊ້ຢູ່"</string> <string name="external_source_trusted" msgid="1146522036773132905">"ອະນຸຍາດແລ້ວ"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"ບໍ່ອະນຸຍາດ"</string> <string name="install_other_apps" msgid="3232595082023199454">"ຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 25b22cae3d0e..058ca607a078 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Valdoma pagal apribotą nustatymą"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nepasiekiama per skambučius"</string> <string name="disabled" msgid="8017887509554714950">"Neleidžiama"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Įgalinta"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Leidžiama"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Neleidžiama"</string> <string name="install_other_apps" msgid="3232595082023199454">"Nežinomų programų diegimas"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 58d80385ff87..384635a97ef8 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikawal oleh Tetapan Terhad"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Tidak tersedia semasa panggilan berlangsung"</string> <string name="disabled" msgid="8017887509554714950">"Dilumpuhkan"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Didayakan"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Dibenarkan"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Tidak dibenarkan"</string> <string name="install_other_apps" msgid="3232595082023199454">"Pasang apl yang tidak diketahui"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index ddd127901e18..fc26db0df2e0 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ကန့်သတ်ဆက်တင်ဖြင့် ထိန်းချုပ်ထားသည်"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ဖုန်းခေါ်ဆိုနေချိန်တွင် မရနိုင်ပါ"</string> <string name="disabled" msgid="8017887509554714950">"ပိတ်ထားပြီး"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"ဖွင့်ထားသည်"</string> <string name="external_source_trusted" msgid="1146522036773132905">"ခွင့်ပြုထားသည်"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"ခွင့်မပြုပါ"</string> <string name="install_other_apps" msgid="3232595082023199454">"အမည်မသိအက်ပ် ထည့်သွင်းခြင်း"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 1a9975732513..d6ac53390403 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por uma definição restrita"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponível durante as chamadas"</string> <string name="disabled" msgid="8017887509554714950">"Desativada"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Ativado"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Autorizada"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Não autorizada"</string> <string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconhecidas"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 7d508862bef1..bae7722cc6e9 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Pod nadzorom omejene nastavitve"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ni na voljo med klici"</string> <string name="disabled" msgid="8017887509554714950">"Onemogočeno"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Omogočeno"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Dovoljene"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Ni dovoljeno"</string> <string name="install_other_apps" msgid="3232595082023199454">"Nameščanje neznanih aplikacij"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index db4f66b955b6..c2f284e0acb6 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"పరిమితం చేసిన సెట్టింగ్ ద్వారా నియంత్రించబడుతుంది"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"కాల్స్ సమయంలో అందుబాటులో ఉండదు"</string> <string name="disabled" msgid="8017887509554714950">"డిజేబుల్ చేయబడింది"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"ఎనేబుల్ చేయబడింది"</string> <string name="external_source_trusted" msgid="1146522036773132905">"అనుమతించినవి"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"అనుమతించబడలేదు"</string> <string name="install_other_apps" msgid="3232595082023199454">"తెలియని యాప్ల ఇన్స్టలేషన్"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 72da3784aa4d..e4b4001352cd 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"محدود کردہ ترتیب کے زیر انتظام ہے"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"کالز کے دوران غیر دستیاب"</string> <string name="disabled" msgid="8017887509554714950">"غیر فعال"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"فعال ہے"</string> <string name="external_source_trusted" msgid="1146522036773132905">"اجازت ہے"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"اجازت نہیں ہے"</string> <string name="install_other_apps" msgid="3232595082023199454">"نامعلوم ایپس انسٹال کریں"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 795eae45ab92..2608a0440804 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -539,8 +539,7 @@ <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Cheklangan sozlama tomonidan boshqariladi"</string> <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Chaqiruv vaqtida ishlamaydi"</string> <string name="disabled" msgid="8017887509554714950">"Oʻchiq"</string> - <!-- no translation found for enabled (3997122818554810678) --> - <skip /> + <string name="enabled" msgid="3997122818554810678">"Yoniq"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Ruxsat berilgan"</string> <string name="external_source_untrusted" msgid="5037891688911672227">"Ruxsat berilmagan"</string> <string name="install_other_apps" msgid="3232595082023199454">"Notanish ilovalarni o‘rnatish"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 03cb1ffbdef1..1297aa3ff7d5 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1510,6 +1510,9 @@ <!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] --> <string name="profile_connect_timeout_subtext">Problem connecting. Turn device off & back on</string> + <!-- Warning message when the bluetooth key is missing. [CHAR_LIMIT=NONE] --> + <string name="bluetooth_key_missing_subtext">Can’t connect</string> + <!-- Name of the 3.5mm audio device. [CHAR LIMIT=40] --> <string name="media_transfer_wired_device_name">Wired audio device</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 3625c002e9d8..7cdc13cb9189 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -36,6 +36,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import androidx.collection.ArraySet; import com.android.settingslib.R; import com.android.settingslib.flags.Flags; @@ -274,29 +275,37 @@ public class BluetoothEventManager { @VisibleForTesting void dispatchActiveDeviceChanged( @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) { - CachedBluetoothDevice targetDevice = activeDevice; + CachedBluetoothDevice mainActiveDevice = activeDevice; for (CachedBluetoothDevice cachedDevice : mDeviceManager.getCachedDevicesCopy()) { - // should report isActive from main device or it will cause trouble to other callers. CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); - CachedBluetoothDevice finalTargetDevice = targetDevice; - if (targetDevice != null - && ((subDevice != null && subDevice.equals(targetDevice)) - || cachedDevice.getMemberDevice().stream().anyMatch( - memberDevice -> memberDevice.equals(finalTargetDevice)))) { - Log.d(TAG, - "The active device is the sub/member device " - + targetDevice.getDevice().getAnonymizedAddress() - + ". change targetDevice as main device " - + cachedDevice.getDevice().getAnonymizedAddress()); - targetDevice = cachedDevice; + Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice(); + final Set<CachedBluetoothDevice> cachedDevices = new ArraySet<>(); + cachedDevices.add(cachedDevice); + if (!memberDevices.isEmpty()) { + cachedDevices.addAll(memberDevices); + } else if (subDevice != null) { + cachedDevices.add(subDevice); + } + + // should report isActive from main device or it will cause trouble to other callers. + if (activeDevice != null + && (cachedDevices.stream().anyMatch( + device -> device.equals(activeDevice)))) { + Log.d(TAG, "The active device is in the set, report main device as active device:" + + cachedDevice.getDevice() + ", active device:" + activeDevice.getDevice()); + mainActiveDevice = cachedDevice; } - boolean isActiveDevice = cachedDevice.equals(targetDevice); - cachedDevice.onActiveDeviceChanged(isActiveDevice, bluetoothProfile); + boolean isActiveDevice = cachedDevice.equals(mainActiveDevice); + cachedDevices.forEach( + device -> device.onActiveDeviceChanged(isActiveDevice, bluetoothProfile)); + //TODO: b/400440223 - Check if we can call DeviceManager.onActiveDeviceChanged & + // Callback.onActiveDeviceChanged for cachedDevices Set also, so we don't need to report + // isActive from main device. mDeviceManager.onActiveDeviceChanged(cachedDevice); } for (BluetoothCallback callback : mCallbacks) { - callback.onActiveDeviceChanged(targetDevice, bluetoothProfile); + callback.onActiveDeviceChanged(mainActiveDevice, bluetoothProfile); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 5f88bcd8d65d..011b2fc15807 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -1495,6 +1495,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> int leftBattery = -1; int rightBattery = -1; + Integer keyMissingCount = BluetoothUtils.getKeyMissingCount(mDevice); + if (keyMissingCount != null && keyMissingCount > 0) { + return mContext.getString(R.string.bluetooth_key_missing_subtext); + } + if (isProfileConnectedFail() && isConnected()) { return mContext.getString(R.string.profile_connect_timeout_subtext); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java index 01d8694256f3..b0f379605f5e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java @@ -19,6 +19,9 @@ package com.android.settingslib.bluetooth; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; import static com.android.settingslib.Utils.isAudioModeOngoingCall; +import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED; +import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED; +import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING; import static java.util.stream.Collectors.toList; @@ -70,9 +73,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -138,6 +143,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { }; private final Context mContext; private final CachedBluetoothDeviceManager mDeviceManager; + private final boolean mHysteresisModeFixAvailable; + private final boolean mIsWorkProfile; private BluetoothLeBroadcast mServiceBroadcast; private BluetoothLeBroadcastAssistant mServiceBroadcastAssistant; private BluetoothLeAudioContentMetadata mBluetoothLeAudioContentMetadata; @@ -158,6 +165,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { // Cached broadcast callbacks being register before service is connected. private ConcurrentHashMap<BluetoothLeBroadcast.Callback, Executor> mCachedBroadcastCallbackExecutorMap = new ConcurrentHashMap<>(); + private Set<BluetoothDevice> mLocalSinksPendingSourceRemoval = new HashSet<>(); private final ServiceListener mServiceListener = new ServiceListener() { @@ -376,6 +384,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { + ", sourceId = " + sourceId); } + mLocalSinksPendingSourceRemoval.remove(sink); } @Override @@ -408,6 +417,35 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { + ", state = " + state); } + if (!Flags.audioStreamMediaServiceByReceiveState()) { + Log.d(TAG, "Skip notifyPrivateBroadcastReceived, flag off."); + return; + } + if (mIsWorkProfile) { + Log.d(TAG, "Skip notifyPrivateBroadcastReceived for work profile."); + return; + } + if (state.getBroadcastId() == mBroadcastId + || !mLocalSinksPendingSourceRemoval.isEmpty()) { + Log.d(TAG, + "Skip notifyPrivateBroadcastReceived, onReceiveStateChanged " + + "triggered by personal audio sharing."); + return; + } + var sourceState = LocalBluetoothLeBroadcastAssistant.getLocalSourceState(state); + if (sourceState == STREAMING || sourceState == DECRYPTION_FAILED + || (mHysteresisModeFixAvailable && sourceState == PAUSED)) { + List<BluetoothLeAudioContentMetadata> subgroupMetadata = + state.getSubgroupMetadata(); + String programInfo = subgroupMetadata.isEmpty() ? "" + : subgroupMetadata.getFirst().getProgramInfo(); + notifyPrivateBroadcastReceived( + sink, + sourceId, + state.getBroadcastId(), + programInfo == null ? "" : programInfo, + sourceState); + } } }; @@ -439,6 +477,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { BluetoothAdapter.getDefaultAdapter() .getProfileProxy( context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); + + mHysteresisModeFixAvailable = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable( + context); + mIsWorkProfile = isWorkProfile(mContext); } /** @@ -1138,6 +1180,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { int localBroadcastId = getLatestBroadcastId(); if (receiveState.getBroadcastId() != localBroadcastId) continue; + mLocalSinksPendingSourceRemoval.add(device); mServiceBroadcastAssistant.removeSource(device, receiveState.getSourceId()); } } @@ -1151,7 +1194,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, disable flag is on"); return; } - if (isWorkProfile(mContext)) { + if (mIsWorkProfile) { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded for work profile."); return; } @@ -1279,7 +1322,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "Skip notifyBroadcastStateChange, not triggered by Settings or SystemUI."); return; } - if (isWorkProfile(mContext)) { + if (mIsWorkProfile) { Log.d(TAG, "Skip notifyBroadcastStateChange, not triggered for work profile."); return; } @@ -1290,6 +1333,26 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { mContext.sendBroadcast(intent); } + private void notifyPrivateBroadcastReceived(BluetoothDevice sink, int sourceId, int broadcastId, + String programInfo, + LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState state) { + String packageName = mContext.getPackageName(); + if (!packageName.equals(SYSUI_PKG)) { + Log.d(TAG, "Skip notifyPrivateBroadcastReceived, not triggered by SystemUI."); + return; + } + var data = new PrivateBroadcastReceiveData(sink, sourceId, broadcastId, programInfo, state); + Intent intent = new Intent(ACTION_LE_AUDIO_PRIVATE_BROADCAST_RECEIVED); + intent.putExtra(EXTRA_PRIVATE_BROADCAST_RECEIVE_DATA, data); + intent.setPackage(SETTINGS_PKG); + Log.d(TAG, + "notifyPrivateBroadcastReceived for sink = " + sink + " with sourceId = " + sourceId + + " state = " + state + + " programInfo =" + programInfo + + " broadcastId = " + broadcastId); + mContext.sendBroadcast(intent); + } + private boolean isWorkProfile(Context context) { UserManager userManager = context.getSystemService(UserManager.class); return userManager != null && userManager.isManagedProfile(); diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt index 58c7907f77de..086516b24047 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt +++ b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt @@ -114,14 +114,19 @@ class FakeZenModeRepository : ZenModeRepository { activeModesDurations.remove(id) } - // Update the active state while maintaining the mode's position in the list + /** Updates a [ZenMode]'s active state, preserving its position in the list. */ private fun updateModeActiveState(id: String, isActive: Boolean) { + updateMode(id) { TestModeBuilder(it).setActive(isActive).build() } + } + + /** Updates a [ZenMode], preserving its position in the list. */ + fun updateMode(id: String, update: (original: ZenMode) -> ZenMode) { val modes = mutableModesFlow.value.toMutableList() val index = modes.indexOfFirst { it.id == id } if (index < 0) { throw IllegalArgumentException("mode $id not found") } - modes[index] = TestModeBuilder(modes[index]).setActive(isActive).build() + modes[index] = update(modes[index]) mutableModesFlow.value = modes } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java index eac6923473b1..2620174e5d39 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java @@ -70,6 +70,9 @@ public class BluetoothEventManagerTest { public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final String DEVICE_NAME = "test_device_name"; + private static final String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11"; + private static final String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22"; + private static final String DEVICE_ADDRESS_3 = "AA:BB:CC:DD:EE:33"; @Mock private LocalBluetoothAdapter mLocalAdapter; @@ -132,6 +135,9 @@ public class BluetoothEventManagerTest { when(mA2dpProfile.isProfileReady()).thenReturn(true); when(mHearingAidProfile.isProfileReady()).thenReturn(true); when(mLeAudioProfile.isProfileReady()).thenReturn(true); + when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1); + when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2); + when(mDevice3.getAddress()).thenReturn(DEVICE_ADDRESS_3); mCachedDevice1 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1); mCachedDevice2 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2); mCachedDevice3 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3); @@ -515,7 +521,6 @@ public class BluetoothEventManagerTest { cachedDevices.add(mCachedDevice2); int group1 = 1; - when(mDevice3.getAddress()).thenReturn("testAddress3"); mCachedDevice1.setGroupId(group1); mCachedDevice3.setGroupId(group1); mCachedDevice1.addMemberDevice(mCachedDevice3); @@ -620,18 +625,32 @@ public class BluetoothEventManagerTest { } @Test - public void dispatchActiveDeviceChanged_activeFromSubDevice_mainCachedDeviceActive() { + public void dispatchActiveDeviceChanged_activeFromSubDevice_bothCachedDevicesActive() { CachedBluetoothDevice subDevice = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3); mCachedDevice1.setSubDevice(subDevice); when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn( Collections.singletonList(mCachedDevice1)); - mCachedDevice1.onProfileStateChanged(mHearingAidProfile, - BluetoothProfile.STATE_CONNECTED); + mCachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); - assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse(); mBluetoothEventManager.dispatchActiveDeviceChanged(subDevice, BluetoothProfile.HEARING_AID); + assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isTrue(); + assertThat(subDevice.isActiveDevice(BluetoothProfile.HEARING_AID)).isTrue(); + } + + @Test + public void dispatchActiveDeviceChanged_activeFromMemberDevice_allCachedDevicesActive() { + mCachedDevice1.addMemberDevice(mCachedDevice2); + when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn( + Collections.singletonList(mCachedDevice1)); + mCachedDevice1.onProfileStateChanged(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED); + + mBluetoothEventManager.dispatchActiveDeviceChanged(mCachedDevice2, + BluetoothProfile.LE_AUDIO); + + assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).isTrue(); + assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).isTrue(); } @Test diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index d929b0de391a..94aa955f0282 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -341,4 +341,7 @@ <!-- The default ringer mode. See `AudioManager` for list of valid values. --> <integer name="def_ringer_mode">2</integer> + + <!-- Caps minsum contrast from -1.0 (Material API) to 0.0 (Android Support)--> + <bool name="config_increaseMinContrast">true</bool> </resources> diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 0121d31b9f35..829d4cb6c772 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -300,5 +300,9 @@ public class SecureSettings { Settings.Secure.DUAL_SHADE, Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED, Settings.Secure.SEARCH_CONTENT_FILTERS_ENABLED, + Settings.Secure.SPELL_CHECKER_ENABLED, + Settings.Secure.SELECTED_SPELL_CHECKER, + // SELECTED_SPELL_CHECKER_SUBTYPE needs to be restored after SELECTED_SPELL_CHECKER + Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 5eb6af62d2c3..d0f84627f8d8 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -472,5 +472,8 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.DUAL_SHADE, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.BROWSER_CONTENT_FILTERS_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.SEARCH_CONTENT_FILTERS_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.SPELL_CHECKER_ENABLED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.SELECTED_SPELL_CHECKER, NULLABLE_COMPONENT_NAME_VALIDATOR); + VALIDATORS.put(Secure.SELECTED_SPELL_CHECKER_SUBTYPE, ANY_INTEGER_VALIDATOR); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index fc402d45c3ec..37ada933259e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -37,10 +37,12 @@ import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.FullBackupDataOutput; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; import android.database.Cursor; import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; @@ -941,6 +943,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { Set<String> blockedSettings = getBlockedSettings(blockedSettingsArrayId); int restoredSettingsCount = 0; + boolean selectedSpellCheckerRestored = false; for (String key : allowlist.mSettingsAllowlist) { boolean isBlockedBySystem = blockedSettings != null && blockedSettings.contains(key); if (isBlockedBySystem || isBlockedByDynamicList(dynamicBlockList, contentUri, key)) { @@ -1068,6 +1071,25 @@ public class SettingsBackupAgent extends BackupAgentHelper { } continue; } + } else if (Settings.Secure.SELECTED_SPELL_CHECKER.equals(key)) { + ServiceInfo si = getServiceInfoOrNull(value); + if (si == null || si.applicationInfo == null) { + Log.i(TAG, "Skipping restore for setting selected_spell_checker " + + "as it is not installed"); + continue; + } else if (!si.applicationInfo.isSystemApp() + && !si.applicationInfo.isUpdatedSystemApp()) { + Log.i(TAG, "Skipping restore for setting selected_spell_checker " + + "as it is not a system app"); + continue; + } + selectedSpellCheckerRestored = true; + } else if (Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE.equals(key)) { + if (!selectedSpellCheckerRestored) { + Log.i(TAG, "Skipping restore for setting selected_spell_checker_subtype " + + "as selected_spell_checker was not restored"); + continue; + } } if (Settings.System.FONT_SCALE.equals(key)) { @@ -1085,6 +1107,21 @@ public class SettingsBackupAgent extends BackupAgentHelper { Log.d(TAG, "Restored font scale from: " + toRestore + " to " + value); } + if (Settings.Secure.CONTRAST_LEVEL.equals(key)) { + boolean increaseMinContrast = getBaseContext().getResources() + .getBoolean(R.bool.config_increaseMinContrast); + + float valueFloat; + try { + valueFloat = Float.parseFloat(value); + } catch (NumberFormatException e) { + valueFloat = 0.0f; + } + + float newValue = Math.max(valueFloat, increaseMinContrast ? 0.0f : -1.0f); + value = String.valueOf(newValue); + } + settingsHelper.restoreValue(this, cr, contentValues, destination, key, value, mRestoredFromSdkInt); @@ -1868,6 +1905,18 @@ public class SettingsBackupAgent extends BackupAgentHelper { return result; } + @Nullable + private ServiceInfo getServiceInfoOrNull(@Nullable String flattenedServiceName) { + if (flattenedServiceName == null) return null; + ComponentName componentName = ComponentName.unflattenFromString(flattenedServiceName); + if (componentName == null) return null; + try { + return getBaseContext().getPackageManager().getServiceInfo(componentName, 0); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + } + /** * Store the allowlist of settings to be backed up and validators for them. */ diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 70c042cb8eba..7179cbdf93fb 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -567,6 +567,7 @@ public class SettingsBackupTest { Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE, Settings.Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, // cache per hearing device Settings.Global.HEARING_DEVICE_LOCAL_NOTIFICATION, // cache per hearing device + Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS, Settings.Global.Wearable.COMBINED_LOCATION_ENABLE, Settings.Global.Wearable.HAS_PAY_TOKENS, Settings.Global.Wearable.GMS_CHECKIN_TIMEOUT_MIN, @@ -749,15 +750,12 @@ public class SettingsBackupTest { Settings.Secure.SECURE_FRP_MODE, Settings.Secure.SEARCH_WEB_RESULTS_OVERRIDE_LIMIT, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, - Settings.Secure.SELECTED_SPELL_CHECKER, // Intentionally removed in Q - Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, // Intentionally removed in Q Settings.Secure.SETTINGS_CLASSNAME, Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, // candidate? Settings.Secure.SHOW_ROTATION_SUGGESTIONS, Settings.Secure.SKIP_FIRST_USE_HINTS, // candidate? Settings.Secure.SLEEP_TIMEOUT, Settings.Secure.SMS_DEFAULT_APPLICATION, - Settings.Secure.SPELL_CHECKER_ENABLED, // Intentionally removed in Q Settings.Secure.TRUST_AGENTS_INITIALIZED, Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, Settings.Secure.TV_APP_USES_NON_SYSTEM_INPUTS, diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java index 48c360b635ea..bc727d33ad4a 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java @@ -16,15 +16,15 @@ package com.android.providers.settings; -import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_NEW_CONFIG; -import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG; import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SIM_SPECIFIC_SETTINGS_2; +import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG; +import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_NEW_CONFIG; import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_SETTINGS_BACKUP_DATA; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertArrayEquals; @@ -35,12 +35,10 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; -import android.annotation.Nullable; import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.BackupAnnotations.OperationType; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; -import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger.DataTypeResult; import android.content.ContentResolver; import android.content.ContentValues; @@ -69,13 +67,11 @@ import androidx.test.runner.AndroidJUnit4; import com.android.window.flags.Flags; -import java.util.List; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -331,6 +327,47 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest { } @Test + public void testOnRestore_minContrastLevelIsRestoredToZero() { + mAgentUnderTest = new TestFriendlySettingsBackupAgent() { + @Override + protected Set<String> getBlockedSettings(int blockedSettingsArrayId) { + return new HashSet<>(); + } + }; + mAgentUnderTest.attach(mContext); + + TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext); + mAgentUnderTest.mSettingsHelper = settingsHelper; + + String contrastLevelValue = "-1.0"; + Map<String, String> settingsToRestore = Map.of(Settings.Secure.CONTRAST_LEVEL, + contrastLevelValue); + + byte[] backupData = generateBackupData(settingsToRestore); + mAgentUnderTest.restoreSettings( + backupData, + /* pos */ 0, + backupData.length, + Settings.Secure.CONTENT_URI, + null, + null, + null, + /* blockedSettingsArrayId */ 0, + Collections.emptySet(), + Collections.emptySet(), + KEY_SECURE); + + // Check that the contrast level has been restored. + assertTrue(settingsHelper.mWrittenValues.containsKey(Settings.Secure.CONTRAST_LEVEL)); + + String restoredContrastLevel = settingsHelper.mWrittenValues.get( + Settings.Secure.CONTRAST_LEVEL); + + float restoredFloat = Float.parseFloat(restoredContrastLevel); + assertEquals(0.0f, restoredFloat, 0.001f); + } + + @Test @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS) public void onCreate_metricsFlagIsDisabled_areAgentMetricsEnabledIsFalse() { mAgentUnderTest.onCreate(); diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml index db733fc33a21..afb337d19282 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="accessibility_menu_service_name" msgid="730136711554740131">"תפריט נגישות"</string> + <string name="accessibility_menu_service_name" msgid="730136711554740131">"תפריט הנגישות"</string> <string name="accessibility_menu_intro" msgid="3164193281544042394">"תפריט הנגישות הוא תפריט גדול שמופיע במסך ומאפשר לשלוט במכשיר. אפשר לנעול את המכשיר, לשלוט בעוצמת הקול ובבהירות, לצלם צילומי מסך ועוד."</string> <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string> <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string> diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java index 71726199aeb6..1543dbe7bb29 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java @@ -46,7 +46,7 @@ import android.hardware.display.DisplayManager; import android.media.AudioManager; import android.os.PowerManager; import android.os.UserManager; -import android.platform.uiautomator_helpers.WaitUtils; +import android.platform.uiautomatorhelpers.WaitUtils; import android.provider.Settings; import android.util.Log; import android.view.Display; diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig index 3cb30258fcb1..c6bc1c70ad18 100644 --- a/packages/SystemUI/aconfig/accessibility.aconfig +++ b/packages/SystemUI/aconfig/accessibility.aconfig @@ -155,3 +155,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "hearing_devices_input_routing_ui_improvement" + namespace: "accessibility" + description: "UI improvement for hearing device input routing feature" + bug: "397314200" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index ab18612355f0..4693377654f8 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -213,18 +213,6 @@ flag { } flag { - name: "notification_undo_guts_on_config_changed" - namespace: "systemui" - description: "Fixes a bug where a theme or font change while notification guts were open" - " (e.g. the snooze options or notification info) would show an empty notification by" - " closing the guts and undoing changes." - bug: "379267630" - metadata { - purpose: PURPOSE_BUGFIX - } -} - -flag { name: "pss_app_selector_recents_split_screen" namespace: "systemui" description: "Allows recent apps selected for partial screenshare to be launched in split screen mode" diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java index ca94482b9c5a..21ec89646f0f 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java @@ -245,6 +245,17 @@ public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner runner.onAnimationCancelled(); finishRunnable.run(); } + + @Override + public void onTransitionConsumed(IBinder transition, boolean aborted) + throws RemoteException { + // Notify the remote runner that the transition has been canceled if the transition + // was merged into another transition or aborted + synchronized (mFinishRunnables) { + mFinishRunnables.remove(transition); + } + runner.onAnimationCancelled(); + } }; } diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt index 80cbbea7659f..362748ec71b0 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt @@ -112,6 +112,24 @@ interface NestedDraggable { interface Controller { /** + * Whether this controller is ready to drag. [onDrag] will be called only if this returns + * `true`, and any drag event will be ignored until then. + * + * This can for instance be used to wait for the content we are dragging to to be composed + * before actually dragging, reducing perceivable jank at the beginning of a drag. + */ + val isReadyToDrag: Boolean + get() = true + + /** + * Whether drags that were started from nested scrolls should be automatically + * [stopped][onDragStopped] as soon as they don't consume the entire `delta` passed to + * [onDrag]. + */ + val autoStopNestedDrags: Boolean + get() = false + + /** * Drag by [delta] pixels. * * @return the consumed [delta]. Any non-consumed delta will be dispatched to the next @@ -266,6 +284,9 @@ private class NestedDraggableNode( /** The pointers currently down, in order of which they were done and mapping to their type. */ private val pointersDown = linkedMapOf<PointerId, PointerType>() + /** Whether the next drag event should be ignored. */ + private var ignoreNextDrag = false + init { delegate(nestedScrollModifierNode(this, nestedScrollDispatcher)) } @@ -418,6 +439,7 @@ private class NestedDraggableNode( velocityTracker: VelocityTracker, ) { velocityTracker.addPointerInputChange(change) + if (shouldIgnoreDrag(controller)) return scrollWithOverscroll(delta.toOffset()) { deltaFromOverscroll -> scrollWithNestedScroll(deltaFromOverscroll) { deltaFromNestedScroll -> @@ -426,6 +448,23 @@ private class NestedDraggableNode( } } + private fun shouldIgnoreDrag(controller: NestedDraggable.Controller): Boolean { + return when { + !controller.isReadyToDrag -> { + // The controller is not ready yet, so we are waiting for an expensive frame to be + // composed. We should ignore this drag and the next one, given that the first delta + // after an expensive frame will be large. + ignoreNextDrag = true + true + } + ignoreNextDrag -> { + ignoreNextDrag = false + true + } + else -> false + } + } + private fun onDragStopped(controller: NestedDraggable.Controller, velocity: Velocity) { // We launch in the scope of the dispatcher so that the fling is not cancelled if this node // is removed right after onDragStopped() is called. @@ -609,8 +648,17 @@ private class NestedDraggableNode( } private fun scrollWithOverscroll(controller: NestedScrollController, offset: Offset): Offset { - return scrollWithOverscroll(offset) { - controller.controller.onDrag(it.toFloat()).toOffset() + if (shouldIgnoreDrag(controller.controller)) return offset + + return scrollWithOverscroll(offset) { delta -> + val available = delta.toFloat() + val consumed = controller.controller.onDrag(available) + if (controller.controller.autoStopNestedDrags && consumed != available) { + controller.ensureOnDragStoppedIsCalled() + this.nestedScrollController = null + } + + consumed.toOffset() } } diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt index a03d769c9c36..b31617369cdb 100644 --- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt +++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt @@ -972,6 +972,36 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw } @Test + fun isReadyToDrag() { + var isReadyToDrag by mutableStateOf(false) + val draggable = TestDraggable(isReadyToDrag = { isReadyToDrag }) + val touchSlop = + rule.setContentWithTouchSlop { + Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation)) + } + + rule.onRoot().performTouchInput { + down(center) + moveBy((touchSlop + 10f).toOffset()) + } + + assertThat(draggable.onDragStartedCalled).isTrue() + assertThat(draggable.onDragDelta).isEqualTo(0f) + + rule.onRoot().performTouchInput { moveBy(20f.toOffset()) } + assertThat(draggable.onDragDelta).isEqualTo(0f) + + // Flag as ready to drag. We still ignore the next drag after that. + isReadyToDrag = true + rule.onRoot().performTouchInput { moveBy(30f.toOffset()) } + assertThat(draggable.onDragDelta).isEqualTo(0f) + + // Now we drag. + rule.onRoot().performTouchInput { moveBy(40f.toOffset()) } + assertThat(draggable.onDragDelta).isEqualTo(40f) + } + + @Test fun consumeNestedPreScroll() { var consumeNestedPreScroll by mutableStateOf(false) val draggable = TestDraggable(shouldConsumeNestedPreScroll = { consumeNestedPreScroll }) @@ -1000,6 +1030,39 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw assertThat(draggable.onDragStartedCalled).isTrue() } + @Test + fun autoStopNestedDrags() { + var consumeScrolls by mutableStateOf(true) + val draggable = + TestDraggable(autoStopNestedDrags = true, onDrag = { if (consumeScrolls) it else 0f }) + + val touchSlop = + rule.setContentWithTouchSlop { + Box( + Modifier.fillMaxSize() + .nestedDraggable(draggable, orientation) + .scrollable(rememberScrollableState { 0f }, orientation) + ) + } + + rule.onRoot().performTouchInput { + down(center) + moveBy((touchSlop + 1f).toOffset()) + } + + assertThat(draggable.onDragStartedCalled).isTrue() + assertThat(draggable.onDragStoppedCalled).isFalse() + + rule.onRoot().performTouchInput { moveBy(50f.toOffset()) } + + assertThat(draggable.onDragStoppedCalled).isFalse() + + consumeScrolls = false + rule.onRoot().performTouchInput { moveBy(1f.toOffset()) } + + assertThat(draggable.onDragStoppedCalled).isTrue() + } + private fun ComposeContentTestRule.setContentWithTouchSlop( content: @Composable () -> Unit ): Float { @@ -1027,6 +1090,8 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw }, private val shouldConsumeNestedPostScroll: (Float) -> Boolean = { true }, private val shouldConsumeNestedPreScroll: (Float) -> Boolean = { false }, + private val isReadyToDrag: () -> Boolean = { true }, + private val autoStopNestedDrags: Boolean = false, ) : NestedDraggable { var shouldStartDrag = true var onDragStartedCalled = false @@ -1056,6 +1121,11 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw onDragStarted.invoke(position, sign) return object : NestedDraggable.Controller { + override val autoStopNestedDrags: Boolean = this@TestDraggable.autoStopNestedDrags + + override val isReadyToDrag: Boolean + get() = isReadyToDrag() + override fun onDrag(delta: Float): Float { onDragCalled = true onDragDelta += delta diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt index 3150e94908cd..2b8fe39c4870 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt @@ -47,6 +47,7 @@ import com.android.compose.animation.scene.observableTransitionState import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState import com.android.compose.animation.scene.transitions import com.android.compose.modifiers.thenIf +import com.android.systemui.Flags import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.CommunalTransitionKeys @@ -104,7 +105,9 @@ val sceneTransitionsV2 = transitions { fade(Communal.Elements.Grid) fade(Communal.Elements.IndicationArea) fade(Communal.Elements.LockIcon) - fade(Communal.Elements.StatusBar) + if (!Flags.glanceableHubV2()) { + fade(Communal.Elements.StatusBar) + } } timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) } } @@ -131,7 +134,9 @@ val sceneTransitions = transitions { fade(Communal.Elements.Grid) fade(Communal.Elements.IndicationArea) fade(Communal.Elements.LockIcon) - fade(Communal.Elements.StatusBar) + if (!Flags.glanceableHubV2()) { + fade(Communal.Elements.StatusBar) + } } timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt index 2d03e2bcdd19..0181928317e1 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.unit.IntRect import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import com.android.compose.animation.scene.ContentScope +import com.android.systemui.Flags import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection @@ -70,8 +71,10 @@ constructor( content = { Box(modifier = Modifier.fillMaxSize()) { with(communalPopupSection) { Popup() } - with(ambientStatusBarSection) { - AmbientStatusBar(modifier = Modifier.fillMaxWidth().zIndex(1f)) + if (!Flags.glanceableHubV2()) { + with(ambientStatusBarSection) { + AmbientStatusBar(modifier = Modifier.fillMaxWidth().zIndex(1f)) + } } CommunalHub( viewModel = viewModel, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt index b04d89d8160f..0b0df06c2015 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt @@ -20,6 +20,7 @@ import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.AnimationVector1D import androidx.compose.animation.core.SpringSpec import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.runtime.withFrameNanos import com.android.compose.animation.scene.content.state.TransitionState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job @@ -47,6 +48,11 @@ internal fun CoroutineScope.animateContent( oneOffAnimation.animatable = it } + if (layoutState.deferTransitionProgress) { + // Defer the animation by one frame so that the transition progress is changed only when + // the expensive first composition frame is done. + withFrameNanos {} + } animatable.animateTo(targetProgress, animationSpec, initialVelocity) } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt index 024ca22069ae..36eafa400090 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt @@ -290,6 +290,15 @@ private class DragControllerImpl( val isDrivingTransition: Boolean get() = layoutState.transitionState == swipeAnimation.contentTransition + override val isReadyToDrag: Boolean + get() { + return !layoutState.deferTransitionProgress || + with(draggableHandler.layoutImpl.elementStateScope) { + swipeAnimation.fromContent.targetSize() != null && + swipeAnimation.toContent.targetSize() != null + } + } + init { check(!isDrivingTransition) { "Multiple controllers with the same SwipeTransition" } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt index 4da83c3a6fc9..a8b676d4ee45 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt @@ -462,7 +462,9 @@ internal class SceneTransitionLayoutImpl( // swipes. .swipeToScene(horizontalDraggableHandler) .swipeToScene(verticalDraggableHandler) - .then(LayoutElement(layoutImpl = this)) + .then( + LayoutElement(layoutImpl = this, transitionState = this.state.transitionState) + ) ) { LookaheadScope { if (_lookaheadScope == null) { @@ -623,23 +625,28 @@ internal class SceneTransitionLayoutImpl( @VisibleForTesting internal fun overlaysOrNullForTest(): Map<OverlayKey, Overlay>? = _overlays } -private data class LayoutElement(private val layoutImpl: SceneTransitionLayoutImpl) : - ModifierNodeElement<LayoutNode>() { - override fun create(): LayoutNode = LayoutNode(layoutImpl) +private data class LayoutElement( + private val layoutImpl: SceneTransitionLayoutImpl, + private val transitionState: TransitionState, +) : ModifierNodeElement<LayoutNode>() { + override fun create(): LayoutNode = LayoutNode(layoutImpl, transitionState) override fun update(node: LayoutNode) { node.layoutImpl = layoutImpl + node.transitionState = transitionState } } -private class LayoutNode(var layoutImpl: SceneTransitionLayoutImpl) : - Modifier.Node(), ApproachLayoutModifierNode, LayoutAwareModifierNode { +private class LayoutNode( + var layoutImpl: SceneTransitionLayoutImpl, + var transitionState: TransitionState, +) : Modifier.Node(), ApproachLayoutModifierNode, LayoutAwareModifierNode { override fun onRemeasured(size: IntSize) { layoutImpl.lastSize = size } override fun isMeasurementApproachInProgress(lookaheadSize: IntSize): Boolean { - return layoutImpl.state.isTransitioning() + return transitionState is TransitionState.Transition.ChangeScene } @ExperimentalComposeUiApi @@ -652,8 +659,7 @@ private class LayoutNode(var layoutImpl: SceneTransitionLayoutImpl) : val width: Int val height: Int - val transition = - layoutImpl.state.currentTransition as? TransitionState.Transition.ChangeScene + val transition = transitionState as? TransitionState.Transition.ChangeScene if (transition == null) { width = placeable.width height = placeable.height @@ -662,6 +668,9 @@ private class LayoutNode(var layoutImpl: SceneTransitionLayoutImpl) : val fromSize = layoutImpl.scene(transition.fromScene).targetSize val toSize = layoutImpl.scene(transition.toScene).targetSize + check(fromSize != Element.SizeUnspecified) { "fromSize is unspecified " } + check(toSize != Element.SizeUnspecified) { "toSize is unspecified" } + // Optimization: make sure we don't read state.progress if fromSize == // toSize to avoid running this code every frame when the layout size does // not change. diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt index 56e8c458ad67..4e28dd569f21 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt @@ -234,6 +234,10 @@ sealed interface MutableSceneTransitionLayoutState : SceneTransitionLayoutState * `from` overlay by `to` overlay. * @param stateLinks the [StateLink] connecting this [SceneTransitionLayoutState] to other * [SceneTransitionLayoutState]s. + * @param deferTransitionProgress whether we should wait for the first composition to be done before + * changing the progress of a transition. This can help reduce perceivable jank at the start of a + * transition in case the first composition of a content takes a lot of time and we are going to + * miss that first frame. */ fun MutableSceneTransitionLayoutState( initialScene: SceneKey, @@ -246,6 +250,9 @@ fun MutableSceneTransitionLayoutState( canReplaceOverlay: (from: OverlayKey, to: OverlayKey) -> Boolean = { _, _ -> true }, onTransitionStart: (TransitionState.Transition) -> Unit = {}, onTransitionEnd: (TransitionState.Transition) -> Unit = {}, + + // TODO(b/400688335): Turn on by default and remove this flag before flexiglass is released. + deferTransitionProgress: Boolean = false, ): MutableSceneTransitionLayoutState { return MutableSceneTransitionLayoutStateImpl( initialScene, @@ -258,6 +265,7 @@ fun MutableSceneTransitionLayoutState( canReplaceOverlay, onTransitionStart, onTransitionEnd, + deferTransitionProgress, ) } @@ -272,6 +280,9 @@ fun rememberMutableSceneTransitionLayoutState( canReplaceOverlay: (from: OverlayKey, to: OverlayKey) -> Boolean = { _, _ -> true }, onTransitionStart: (TransitionState.Transition) -> Unit = {}, onTransitionEnd: (TransitionState.Transition) -> Unit = {}, + + // TODO(b/400688335): Turn on by default and remove this flag before flexiglass is released. + deferTransitionProgress: Boolean = false, ): MutableSceneTransitionLayoutState { val motionScheme = MaterialTheme.motionScheme val layoutState = remember { @@ -286,6 +297,7 @@ fun rememberMutableSceneTransitionLayoutState( canReplaceOverlay = canReplaceOverlay, onTransitionStart = onTransitionStart, onTransitionEnd = onTransitionEnd, + deferTransitionProgress = deferTransitionProgress, ) } @@ -298,6 +310,7 @@ fun rememberMutableSceneTransitionLayoutState( layoutState.canReplaceOverlay = canReplaceOverlay layoutState.onTransitionStart = onTransitionStart layoutState.onTransitionEnd = onTransitionEnd + layoutState.deferTransitionProgress = deferTransitionProgress } return layoutState } @@ -317,6 +330,8 @@ internal class MutableSceneTransitionLayoutStateImpl( }, internal var onTransitionStart: (TransitionState.Transition) -> Unit = {}, internal var onTransitionEnd: (TransitionState.Transition) -> Unit = {}, + // TODO(b/400688335): Turn on by default and remove this flag before flexiglass is released. + internal var deferTransitionProgress: Boolean = false, ) : MutableSceneTransitionLayoutState { private val creationThread: Thread = Thread.currentThread() diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt index 2d2a81542f84..5d4232d8a8b7 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt @@ -38,7 +38,7 @@ internal class ElementStateScopeImpl(private val layoutImpl: SceneTransitionLayo } override fun ContentKey.targetSize(): IntSize? { - return layoutImpl.content(this).targetSize.takeIf { it != IntSize.Zero } + return layoutImpl.content(this).targetSize.takeIf { it != Element.SizeUnspecified } } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt index 90bf92ae1dd0..7492f3737edc 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt @@ -93,9 +93,10 @@ internal sealed class Content( val containerState = ContainerState() // Important: All fields in this class should be backed by State given that contents are updated - // directly during composition, outside of a SideEffect. + // directly during composition, outside of a SideEffect, or are observed during composition, + // layout or drawing. var content by mutableStateOf(content) - var targetSize by mutableStateOf(IntSize.Zero) + var targetSize by mutableStateOf(Element.SizeUnspecified) var userActions by mutableStateOf(actions) var zIndex by mutableFloatStateOf(zIndex) @@ -212,9 +213,17 @@ private class ContentNode( return if (isElevationPossible) delegate(ContainerNode(content.containerState)) else null } + override fun onDetach() { + this.content.targetSize = Element.SizeUnspecified + } + fun update(content: Content, isElevationPossible: Boolean, isInvisible: Boolean) { - if (content != this.content || isElevationPossible != this.isElevationPossible) { + if (content != this.content) { + this.content.targetSize = Element.SizeUnspecified this.content = content + } + + if (content != this.content || isElevationPossible != this.isElevationPossible) { this.isElevationPossible = isElevationPossible containerDelegate?.let { undelegate(it) } diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json index 57f67665242c..770f85969ed1 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json @@ -59,10 +59,7 @@ 896, 912, 928, - 944, - 960, - 976, - 992 + 944 ], "features": [ { @@ -70,256 +67,244 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50.4 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 8.4, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 11.2, + "y": 5.2 }, { - "x": 52.4, - "y": 50 + "x": 13.6, + "y": 5.2 }, { - "x": 56, - "y": 50 + "x": 15.6, + "y": 5.2 }, { - "x": 58.8, - "y": 50 + "x": 16.8, + "y": 5.2 }, { - "x": 60.8, - "y": 50 + "x": 17.6, + "y": 5.2 }, { - "x": 62, - "y": 50 + "x": 18.4, + "y": 5.2 }, { - "x": 62.8, - "y": 50 + "x": 18.8, + "y": 5.2 }, { - "x": 63.6, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 - }, - { - "x": 64, - "y": 50 - }, - { - "x": 64, - "y": 50 - }, - { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 } ] }, @@ -328,255 +313,243 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 - }, - { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 393.2 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 393.2 + "width": 150, + "height": 292.8 }, { - "width": 188, - "height": 386 + "width": 150, + "height": 292.8 }, { - "width": 188, - "height": 379.6 + "width": 150, + "height": 286 }, { - "width": 188, - "height": 372.8 + "width": 150, + "height": 279.6 }, { - "width": 188, - "height": 366.8 + "width": 150, + "height": 273.2 }, { - "width": 188, - "height": 360.4 + "width": 150, + "height": 266.8 }, { - "width": 188, - "height": 354 + "width": 150, + "height": 260.4 }, { - "width": 188, - "height": 347.6 + "width": 150, + "height": 254 }, { - "width": 188, - "height": 341.2 + "width": 150, + "height": 247.6 }, { - "width": 188, - "height": 341.2 + "width": 150, + "height": 241.2 }, { - "width": 188, - "height": 334 + "width": 150, + "height": 241.2 }, { - "width": 188, - "height": 328 + "width": 150, + "height": 234.4 }, { - "width": 188, - "height": 321.6 + "width": 150, + "height": 228 }, { - "width": 188, - "height": 315.2 + "width": 150, + "height": 221.6 }, { - "width": 188, - "height": 308.8 + "width": 150, + "height": 215.2 }, { - "width": 188, - "height": 302.4 + "width": 150, + "height": 208.8 }, { - "width": 188, - "height": 296 + "width": 150, + "height": 202 }, { - "width": 188, - "height": 289.6 + "width": 150, + "height": 195.6 }, { - "width": 188, - "height": 289.6 + "width": 150, + "height": 189.2 }, { - "width": 188, - "height": 282.8 + "width": 150, + "height": 189.2 }, { - "width": 188, - "height": 276.4 + "width": 150, + "height": 182.8 }, { - "width": 188, - "height": 270 + "width": 150, + "height": 176.4 }, { - "width": 188, - "height": 263.6 + "width": 150, + "height": 170 }, { - "width": 188, - "height": 257.2 + "width": 150, + "height": 163.6 }, { - "width": 188, - "height": 250.8 + "width": 150, + "height": 157.2 }, { - "width": 188, - "height": 244.4 + "width": 150, + "height": 150.8 }, { - "width": 188, - "height": 238 + "width": 150, + "height": 144.4 }, { - "width": 188, - "height": 238 + "width": 150, + "height": 137.6 }, { - "width": 188, - "height": 231.2 + "width": 150, + "height": 137.6 }, { - "width": 188, - "height": 224.8 + "width": 150, + "height": 131.2 }, { - "width": 188, - "height": 218.4 + "width": 150, + "height": 124.8 }, { - "width": 188, - "height": 212 + "width": 150, + "height": 118.4 }, { - "width": 188, - "height": 212 + "width": 150, + "height": 112 }, { - "width": 188, - "height": 192.4 + "width": 150, + "height": 112 }, { - "width": 188, - "height": 159.6 + "width": 150, + "height": 99.2 }, { - "width": 188, - "height": 124.4 + "width": 150, + "height": 81.2 }, { - "width": 188, - "height": 92.8 + "width": 144, + "height": 62.8 }, { - "width": 183.2, - "height": 66.4 + "width": 138, + "height": 46.4 }, { - "width": 176, - "height": 46 + "width": 133.2, + "height": 32 }, { - "width": 170.4, - "height": 28.8 + "width": 129.6, + "height": 20.4 }, { - "width": 166.8, - "height": 15.2 + "width": 127.2, + "height": 12 }, { - "width": 164, + "width": 125.2, "height": 6.4 }, { - "width": 162.4, - "height": 0.8 + "width": 124, + "height": 2.8 }, { - "width": 161.2, - "height": 0 + "width": 123.2, + "height": 0.4 }, { - "width": 160.4, + "width": 122.4, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, - "height": 0 - }, - { - "width": 160, - "height": 0 - }, - { - "width": 160, + "width": 122, "height": 0 } ] @@ -627,22 +600,19 @@ 1, 1, 1, - 1, - 1, - 0.9808927, - 0.8211168, - 0.61845565, - 0.43834114, - 0.29850912, - 0.19755232, - 0.12793064, - 0.08142871, - 0.051099956, - 0.031684637, - 0.019442618, - 0.011821032, - 0, - 0, + 0.99781144, + 0.87040234, + 0.6695792, + 0.48078007, + 0.33033127, + 0.22004372, + 0.1432175, + 0.09153092, + 0.057634592, + 0.035840213, + 0.022048414, + 0.013435662, + 0.008117795, 0, 0, 0, diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json index 01bc852cf7f4..6b7de56c1da6 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json @@ -69,252 +69,252 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50.8, - "y": 52 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 52.4, - "y": 50 + "x": 6.8, + "y": 5.2 }, { - "x": 55.6, - "y": 50 + "x": 10.4, + "y": 5.2 }, { - "x": 58.4, - "y": 50 + "x": 13.2, + "y": 5.2 }, { - "x": 60.4, - "y": 50 + "x": 15.2, + "y": 5.2 }, { - "x": 61.6, - "y": 50 + "x": 16.8, + "y": 5.2 }, { - "x": 62.8, - "y": 50 + "x": 17.6, + "y": 5.2 }, { - "x": 63.2, - "y": 50 + "x": 18.4, + "y": 5.2 }, { - "x": 63.6, - "y": 50 + "x": 18.8, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 } ] }, @@ -323,251 +323,251 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 390 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 390 + "width": 150, + "height": 297.6 }, { - "width": 188, - "height": 379.2 + "width": 150, + "height": 292.4 }, { - "width": 188, - "height": 371.2 + "width": 150, + "height": 287.6 }, { - "width": 188, - "height": 363.2 + "width": 150, + "height": 282.8 }, { - "width": 188, - "height": 355.2 + "width": 150, + "height": 278 }, { - "width": 188, - "height": 347.2 + "width": 150, + "height": 273.2 }, { - "width": 188, - "height": 339.2 + "width": 150, + "height": 268.4 }, { - "width": 188, - "height": 331.2 + "width": 150, + "height": 263.6 }, { - "width": 188, - "height": 323.2 + "width": 150, + "height": 258.8 }, { - "width": 188, - "height": 323.2 + "width": 150, + "height": 258.8 }, { - "width": 188, - "height": 314.8 + "width": 150, + "height": 253.6 }, { - "width": 188, - "height": 306.8 + "width": 150, + "height": 248.8 }, { - "width": 188, - "height": 298.8 + "width": 150, + "height": 244 }, { - "width": 188, - "height": 290.8 + "width": 150, + "height": 239.2 }, { - "width": 188, - "height": 282.8 + "width": 150, + "height": 234.4 }, { - "width": 188, - "height": 274.8 + "width": 150, + "height": 229.6 }, { - "width": 188, - "height": 266.8 + "width": 150, + "height": 224.8 }, { - "width": 188, - "height": 258.8 + "width": 150, + "height": 220 }, { - "width": 188, - "height": 258.8 + "width": 150, + "height": 220 }, { - "width": 188, - "height": 250.4 + "width": 150, + "height": 214.8 }, { - "width": 188, - "height": 242.4 + "width": 150, + "height": 210 }, { - "width": 188, - "height": 234.4 + "width": 150, + "height": 205.2 }, { - "width": 188, - "height": 226.4 + "width": 150, + "height": 200.4 }, { - "width": 188, - "height": 218.4 + "width": 150, + "height": 195.6 }, { - "width": 188, - "height": 210.4 + "width": 150, + "height": 190.8 }, { - "width": 188, - "height": 202.4 + "width": 150, + "height": 186 }, { - "width": 188, - "height": 194.4 + "width": 150, + "height": 181.2 }, { - "width": 188, - "height": 194.4 + "width": 150, + "height": 181.2 }, { - "width": 188, - "height": 185.6 + "width": 150, + "height": 176.4 }, { - "width": 188, - "height": 178 + "width": 150, + "height": 171.6 }, { - "width": 188, - "height": 170 + "width": 150, + "height": 166.8 }, { - "width": 188, + "width": 150, "height": 161.6 }, { - "width": 188, + "width": 150, "height": 161.6 }, { - "width": 188, - "height": 144.8 + "width": 150, + "height": 147.2 }, { - "width": 188, - "height": 118.8 + "width": 150, + "height": 122 }, { - "width": 188, - "height": 92 + "width": 150, + "height": 95.2 }, { - "width": 183.6, - "height": 68 + "width": 146.8, + "height": 70.8 }, { - "width": 176.8, - "height": 48.4 + "width": 139.6, + "height": 50.8 }, { - "width": 171.6, - "height": 32 + "width": 134, + "height": 34 }, { - "width": 167.6, - "height": 18 + "width": 130, + "height": 19.2 }, { - "width": 164.8, - "height": 8.8 + "width": 127.2, + "height": 9.2 }, { - "width": 162.8, + "width": 125.2, "height": 2.8 }, { - "width": 161.6, + "width": 123.6, "height": 0 }, { - "width": 160.8, + "width": 122.8, "height": 0 }, { - "width": 160.4, + "width": 122.4, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 } ] @@ -619,19 +619,19 @@ 1, 1, 1, - 0.9967737, - 0.86538374, - 0.66414475, - 0.47619528, - 0.32686388, - 0.21757984, - 0.14153665, - 0.09041709, - 0.05691254, - 0.035380244, - 0.02175957, - 0.01325649, - 0.008007765, + 0.99979615, + 0.8860379, + 0.6869267, + 0.4955439, + 0.34154767, + 0.22803628, + 0.14868057, + 0.09515619, + 0.059987247, + 0.037340224, + 0.02299112, + 0.01402092, + 0.008477271, 0, 0, 0, diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json index b6e423afc6c4..13f75d2adfb4 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json @@ -68,200 +68,200 @@ "type": "not_found" }, { - "x": 62.8, - "y": 50 + "x": 18, + "y": 5.2 }, { - "x": 62.8, - "y": 50 + "x": 18, + "y": 5.2 }, { - "x": 61.6, - "y": 50 + "x": 16.8, + "y": 5.2 }, { - "x": 60.8, - "y": 50 + "x": 16, + "y": 5.2 }, { - "x": 59.6, - "y": 50 + "x": 14.8, + "y": 5.2 }, { - "x": 58.4, - "y": 50 + "x": 13.6, + "y": 5.2 }, { - "x": 57.2, - "y": 50 + "x": 12.4, + "y": 5.2 }, { - "x": 56, - "y": 50 + "x": 11.2, + "y": 5.2 }, { - "x": 55.2, - "y": 50 + "x": 10.4, + "y": 5.2 }, { - "x": 54, - "y": 50 + "x": 9.2, + "y": 5.2 }, { - "x": 54, - "y": 50 + "x": 9.2, + "y": 5.2 }, { - "x": 52.8, - "y": 50 + "x": 8, + "y": 5.2 }, { - "x": 51.6, - "y": 50 + "x": 6.8, + "y": 5.2 }, { - "x": 50.4, - "y": 50 + "x": 5.6, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -279,200 +279,200 @@ "type": "not_found" }, { - "width": 162.4, + "width": 124.4, "height": 1.6 }, { - "width": 162.4, + "width": 124.4, "height": 1.6 }, { - "width": 164.8, + "width": 126.8, "height": 3.2 }, { - "width": 166.8, + "width": 128.8, "height": 4.8 }, { - "width": 169.2, + "width": 131.2, "height": 6.4 }, { - "width": 171.6, + "width": 133.6, "height": 8 }, { - "width": 173.6, + "width": 135.6, "height": 9.6 }, { - "width": 176, + "width": 138, "height": 11.2 }, { - "width": 178, + "width": 140, "height": 12.8 }, { - "width": 180.4, + "width": 142.4, "height": 14.4 }, { - "width": 180.4, + "width": 142.4, "height": 14.4 }, { - "width": 182.8, + "width": 144.8, "height": 16.4 }, { - "width": 185.2, + "width": 147.2, "height": 18 }, { - "width": 187.2, + "width": 149.2, "height": 19.6 }, { - "width": 188, + "width": 150, "height": 25.6 }, { - "width": 188, + "width": 150, "height": 36.4 }, { - "width": 188, + "width": 150, "height": 45.6 }, { - "width": 188, + "width": 150, "height": 59.2 }, { - "width": 188, + "width": 150, "height": 72.8 }, { - "width": 188, + "width": 150, "height": 79.6 }, { - "width": 188, + "width": 150, "height": 92.8 }, { - "width": 188, + "width": 150, "height": 104.4 }, { - "width": 188, + "width": 150, "height": 115.2 }, { - "width": 188, + "width": 150, "height": 125.2 }, { - "width": 188, + "width": 150, "height": 134.8 }, { - "width": 188, + "width": 150, "height": 143.2 }, { - "width": 188, + "width": 150, "height": 151.2 }, { - "width": 188, + "width": 150, "height": 158.8 }, { - "width": 188, + "width": 150, "height": 160 }, { - "width": 188, + "width": 150, "height": 167.2 }, { - "width": 188, + "width": 150, "height": 174.4 }, { - "width": 188, + "width": 150, "height": 180.8 }, { - "width": 188, + "width": 150, "height": 187.6 }, { - "width": 188, + "width": 150, "height": 188 }, { - "width": 188, - "height": 207.2 + "width": 150, + "height": 200.4 }, { - "width": 188, - "height": 240 + "width": 150, + "height": 218.4 }, { - "width": 188, - "height": 275.2 + "width": 150, + "height": 236.8 }, { - "width": 188, - "height": 306.8 + "width": 150, + "height": 253.2 }, { - "width": 188, - "height": 333.2 + "width": 150, + "height": 266.8 }, { - "width": 188, - "height": 353.6 + "width": 150, + "height": 277.2 }, { - "width": 188, - "height": 368.8 + "width": 150, + "height": 284.8 }, { - "width": 188, - "height": 380 + "width": 150, + "height": 290 }, { - "width": 188, - "height": 387.6 + "width": 150, + "height": 294 }, { - "width": 188, - "height": 392.4 + "width": 150, + "height": 296.4 }, { - "width": 188, - "height": 395.6 + "width": 150, + "height": 298 }, { - "width": 188, - "height": 398 + "width": 150, + "height": 298.8 }, { - "width": 188, - "height": 398.8 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 } ] }, @@ -494,12 +494,12 @@ 0, 0, 0.0067873597, - 0.0612576, - 0.19080025, + 0.06125766, + 0.19080031, 0.39327443, 0.5711931, - 0.70855826, - 0.8074064, + 0.7085583, + 0.8074065, 0.8754226, 0.9207788, 0.95032376, diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json index a82db346ed58..015df8fd02fb 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json @@ -40,8 +40,7 @@ 592, 608, 624, - 640, - 656 + 640 ], "features": [ { @@ -49,172 +48,168 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50.4, - "y": 50.8 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 6.4, + "y": 5.2 }, { - "x": 51.2, - "y": 50 + "x": 10.4, + "y": 5.2 }, { - "x": 55.6, - "y": 50 + "x": 13.6, + "y": 5.2 }, { - "x": 58.8, - "y": 50 + "x": 15.6, + "y": 5.2 }, { - "x": 60.8, - "y": 50 + "x": 17.2, + "y": 5.2 }, { - "x": 62, - "y": 50 + "x": 18, + "y": 5.2 }, { - "x": 63.2, - "y": 50 + "x": 18.8, + "y": 5.2 }, { - "x": 63.6, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 - }, - { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 } ] }, @@ -223,171 +218,167 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 - }, - { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 389.6 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 378.8 + "width": 150, + "height": 288.8 }, { - "width": 188, - "height": 366 + "width": 150, + "height": 278.8 }, { - "width": 188, - "height": 352 + "width": 150, + "height": 266 }, { - "width": 188, - "height": 352 + "width": 150, + "height": 252 }, { - "width": 188, - "height": 316.8 + "width": 150, + "height": 252 }, { - "width": 188, - "height": 261.2 + "width": 150, + "height": 224 }, { - "width": 188, - "height": 202.8 + "width": 150, + "height": 183.2 }, { - "width": 188, - "height": 150.8 + "width": 150, + "height": 141.6 }, { - "width": 188, - "height": 107.6 + "width": 150, + "height": 104.4 }, { - "width": 186, + "width": 148, "height": 74.4 }, { - "width": 177.2, - "height": 49.6 + "width": 139.6, + "height": 51.2 }, { - "width": 170.8, - "height": 29.6 + "width": 133.6, + "height": 32.4 }, { - "width": 166.8, - "height": 12.8 + "width": 129.6, + "height": 15.6 }, { - "width": 164, - "height": 2.4 + "width": 126.4, + "height": 5.2 }, { - "width": 162, + "width": 124.4, "height": 0 }, { - "width": 160.8, + "width": 123.2, "height": 0 }, { - "width": 160.4, + "width": 122.4, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 } ] @@ -418,20 +409,19 @@ 1, 1, 1, - 1, - 0.9833227, - 0.8263634, - 0.623688, - 0.44261706, - 0.3016883, - 0.1997872, - 0.12944388, - 0.08242595, - 0.051743627, - 0.032093227, - 0.019698441, - 0.0119793415, - 0, + 0.99532944, + 0.8594856, + 0.65783304, + 0.47089338, + 0.32286334, + 0.21474117, + 0.139602, + 0.089136004, + 0.056082606, + 0.03485179, + 0.02142787, + 0.013050735, + 0.007881463, 0, 0, 0, diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json index 6dc5a0e79e81..f202fcd5f59c 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json @@ -64,104 +64,104 @@ "type": "not_found" }, { - "x": 62.4, - "y": 50 + "x": 17.6, + "y": 5.2 }, { - "x": 61.2, - "y": 50 + "x": 16.4, + "y": 5.2 }, { - "x": 59.2, - "y": 50 + "x": 14.4, + "y": 5.2 }, { - "x": 57.2, - "y": 50 + "x": 12.4, + "y": 5.2 }, { - "x": 54.8, - "y": 50 + "x": 10, + "y": 5.2 }, { - "x": 52.4, - "y": 50 + "x": 7.6, + "y": 5.2 }, { - "x": 52.4, - "y": 50 + "x": 7.6, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -194,104 +194,104 @@ "type": "not_found" }, { - "width": 163.2, + "width": 125.2, "height": 2 }, { - "width": 166, + "width": 128, "height": 4.4 }, { - "width": 170, + "width": 132, "height": 6.8 }, { - "width": 174, + "width": 136, "height": 10 }, { - "width": 178.4, + "width": 140.4, "height": 13.2 }, { - "width": 183.6, + "width": 145.6, "height": 16.8 }, { - "width": 183.6, + "width": 145.6, "height": 16.8 }, { - "width": 188, - "height": 44.4 + "width": 150, + "height": 36.8 }, { - "width": 188, - "height": 103.6 + "width": 150, + "height": 81.2 }, { - "width": 188, - "height": 166 + "width": 150, + "height": 126.8 }, { - "width": 188, - "height": 222.4 + "width": 150, + "height": 168 }, { - "width": 188, - "height": 270 + "width": 150, + "height": 202.8 }, { - "width": 188, - "height": 307.2 + "width": 150, + "height": 230 }, { - "width": 188, - "height": 335.6 + "width": 150, + "height": 250.8 }, { - "width": 188, - "height": 356.4 + "width": 150, + "height": 266.4 }, { - "width": 188, - "height": 371.2 + "width": 150, + "height": 277.6 }, { - "width": 188, - "height": 381.6 + "width": 150, + "height": 285.2 }, { - "width": 188, - "height": 388.8 + "width": 150, + "height": 290.4 }, { - "width": 188, - "height": 393.2 + "width": 150, + "height": 294 }, { - "width": 188, - "height": 396 + "width": 150, + "height": 296.4 }, { - "width": 188, - "height": 398 + "width": 150, + "height": 298 }, { - "width": 188, - "height": 398.8 + "width": 150, + "height": 298.8 }, { - "width": 188, - "height": 399.2 + "width": 150, + "height": 299.2 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 } ] }, diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json index 1cd971aa2898..4c57bda8fd5a 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json @@ -89,268 +89,268 @@ "type": "not_found" }, { - "x": 62.8, - "y": 50 + "x": 18, + "y": 5.2 }, { - "x": 62, - "y": 50 + "x": 17.2, + "y": 5.2 }, { - "x": 61.2, - "y": 50 + "x": 16.4, + "y": 5.2 }, { - "x": 60.4, - "y": 50 + "x": 15.6, + "y": 5.2 }, { - "x": 59.6, - "y": 50 + "x": 14.8, + "y": 5.2 }, { - "x": 58.8, - "y": 50 + "x": 14, + "y": 5.2 }, { - "x": 58, - "y": 50 + "x": 13.2, + "y": 5.2 }, { - "x": 57.2, - "y": 50 + "x": 12.4, + "y": 5.2 }, { - "x": 56.4, - "y": 50 + "x": 11.6, + "y": 5.2 }, { - "x": 55.6, - "y": 50 + "x": 10.8, + "y": 5.2 }, { - "x": 55.2, - "y": 50 + "x": 10.4, + "y": 5.2 }, { - "x": 54.4, - "y": 50 + "x": 9.6, + "y": 5.2 }, { - "x": 53.6, - "y": 50 + "x": 8.8, + "y": 5.2 }, { - "x": 53.2, - "y": 50 + "x": 8.4, + "y": 5.2 }, { - "x": 52.8, - "y": 50 + "x": 8, + "y": 5.2 }, { - "x": 52, - "y": 50 + "x": 7.2, + "y": 5.2 }, { - "x": 51.6, - "y": 50 + "x": 6.8, + "y": 5.2 }, { - "x": 51.2, - "y": 50 + "x": 6.4, + "y": 5.2 }, { - "x": 50.8, - "y": 50 + "x": 6, + "y": 5.2 }, { - "x": 50.4, - "y": 50 + "x": 5.6, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50.4, - "y": 50 + "x": 5.6, + "y": 5.2 }, { - "x": 50.8, - "y": 50 + "x": 6, + "y": 5.2 }, { - "x": 51.2, - "y": 50 + "x": 6.4, + "y": 5.2 }, { - "x": 51.6, - "y": 50 + "x": 6.8, + "y": 5.2 }, { - "x": 52, - "y": 50 + "x": 7.2, + "y": 5.2 }, { - "x": 52.8, - "y": 50 + "x": 8, + "y": 5.2 }, { - "x": 53.2, - "y": 50 + "x": 8.4, + "y": 5.2 }, { - "x": 53.6, - "y": 50 + "x": 8.8, + "y": 5.2 }, { - "x": 54.4, - "y": 50 + "x": 9.6, + "y": 5.2 }, { - "x": 55.2, - "y": 50 + "x": 10.4, + "y": 5.2 }, { - "x": 55.6, - "y": 50 + "x": 10.8, + "y": 5.2 }, { - "x": 56.4, - "y": 50 + "x": 11.6, + "y": 5.2 }, { - "x": 57.2, - "y": 50 + "x": 12.4, + "y": 5.2 }, { - "x": 58, - "y": 50 + "x": 13.2, + "y": 5.2 }, { - "x": 58.8, - "y": 50 + "x": 14, + "y": 5.2 }, { - "x": 59.6, - "y": 50 + "x": 14.8, + "y": 5.2 }, { - "x": 60.4, - "y": 50 + "x": 15.6, + "y": 5.2 }, { - "x": 61.2, - "y": 50 + "x": 16.4, + "y": 5.2 }, { - "x": 62, - "y": 50 + "x": 17.2, + "y": 5.2 }, { - "x": 62.8, - "y": 50 + "x": 18, + "y": 5.2 }, { - "x": 63.6, - "y": 50 + "x": 18.8, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 } ] }, @@ -371,267 +371,267 @@ "type": "not_found" }, { - "width": 162.4, + "width": 124.4, "height": 1.6 }, { - "width": 164, + "width": 126, "height": 2.8 }, { - "width": 166, + "width": 128, "height": 4 }, { - "width": 167.6, + "width": 129.6, "height": 5.2 }, { - "width": 169.2, + "width": 131.2, "height": 6.4 }, { - "width": 170.8, + "width": 132.8, "height": 7.6 }, { - "width": 172.4, + "width": 134.4, "height": 8.8 }, { - "width": 174, + "width": 136, "height": 10 }, { - "width": 175.2, + "width": 137.2, "height": 10.8 }, { - "width": 176.8, + "width": 138.8, "height": 12 }, { - "width": 178, + "width": 140, "height": 12.8 }, { - "width": 179.2, + "width": 141.2, "height": 13.6 }, { - "width": 180.8, + "width": 142.8, "height": 14.8 }, { - "width": 182, + "width": 144, "height": 15.6 }, { - "width": 182.8, + "width": 144.8, "height": 16.4 }, { - "width": 184, + "width": 146, "height": 17.2 }, { - "width": 184.8, + "width": 146.8, "height": 17.6 }, { - "width": 186, + "width": 148, "height": 18.4 }, { - "width": 186.8, + "width": 148.8, "height": 19.2 }, { - "width": 187.6, + "width": 149.6, "height": 19.6 }, { - "width": 188, + "width": 150, "height": 21.2 }, { - "width": 188, + "width": 150, "height": 24.8 }, { - "width": 188, + "width": 150, "height": 30 }, { - "width": 188, + "width": 150, "height": 38 }, { - "width": 188, + "width": 150, "height": 46 }, { - "width": 188, + "width": 150, "height": 54 }, { - "width": 188, + "width": 150, "height": 61.2 }, { - "width": 188, + "width": 150, "height": 66.8 }, { - "width": 188, + "width": 150, "height": 71.6 }, { - "width": 188, + "width": 150, "height": 75.6 }, { - "width": 188, + "width": 150, "height": 78 }, { - "width": 188, + "width": 150, "height": 79.6 }, { - "width": 188, + "width": 150, "height": 80.8 }, { - "width": 188, + "width": 150, "height": 80.8 }, { - "width": 188, + "width": 150, "height": 80.4 }, { - "width": 188, + "width": 150, "height": 79.6 }, { - "width": 187.6, + "width": 149.6, "height": 78 }, { - "width": 186.8, + "width": 148.8, "height": 76.4 }, { - "width": 186, + "width": 148, "height": 74 }, { - "width": 184.8, + "width": 146.8, "height": 71.6 }, { - "width": 184, + "width": 146, "height": 69.2 }, { - "width": 182.8, + "width": 144.8, "height": 66 }, { - "width": 182, + "width": 144, "height": 62.8 }, { - "width": 180.8, + "width": 142.8, "height": 59.2 }, { - "width": 179.2, + "width": 141.2, "height": 55.6 }, { - "width": 178, + "width": 140, "height": 52 }, { - "width": 176.8, + "width": 138.8, "height": 48 }, { - "width": 175.2, + "width": 137.2, "height": 44 }, { - "width": 174, + "width": 136, "height": 40 }, { - "width": 172.4, + "width": 134.4, "height": 37.6 }, { - "width": 170.8, + "width": 132.8, "height": 38 }, { - "width": 169.2, + "width": 131.2, "height": 30.4 }, { - "width": 167.6, + "width": 129.6, "height": 25.2 }, { - "width": 166, + "width": 128, "height": 20.4 }, { - "width": 164, + "width": 126, "height": 16 }, { - "width": 162.4, + "width": 124.4, "height": 12.4 }, { - "width": 160.8, + "width": 122.8, "height": 9.2 }, { - "width": 160, + "width": 122, "height": 6.8 }, { - "width": 160, + "width": 122, "height": 5.2 }, { - "width": 160, + "width": 122, "height": 3.6 }, { - "width": 160, + "width": 122, "height": 2.4 }, { - "width": 160, + "width": 122, "height": 1.6 }, { - "width": 160, + "width": 122, "height": 0.8 }, { - "width": 160, + "width": 122, "height": 0.4 }, { - "width": 160, + "width": 122, "height": 0.4 }, { - "width": 160, + "width": 122, "height": 0 } ] @@ -658,10 +658,10 @@ 0, 0.012518823, 0.0741024, - 0.2254293, + 0.22542936, 0.42628878, - 0.5976641, - 0.7280312, + 0.5976642, + 0.7280313, 0.82100236, 0.8845844, 0.9267946, @@ -706,17 +706,17 @@ 1, 0.9944124, 0.9417388, - 0.8184184, - 0.6157812, - 0.4361611, - 0.2968906, - 0.19641554, - 0.12716137, - 0.080921985, - 0.050773025, - 0.03147719, - 0.019312752, - 0.011740655, + 0.81841844, + 0.61578125, + 0.43616113, + 0.29689062, + 0.19641556, + 0.12716138, + 0.080922, + 0.050773032, + 0.031477194, + 0.019312754, + 0.011740657, 0 ] } diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json index 1030455e873f..26c80e331f81 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json @@ -28,8 +28,7 @@ 400, 416, 432, - 448, - 464 + 448 ], "features": [ { @@ -37,124 +36,120 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 7.2, + "y": 5.2 }, { - "x": 53.2, - "y": 50 + "x": 11.2, + "y": 5.2 }, { - "x": 57.2, - "y": 50 + "x": 14, + "y": 5.2 }, { - "x": 59.6, - "y": 50 + "x": 16, + "y": 5.2 }, { - "x": 61.6, - "y": 50 + "x": 17.6, + "y": 5.2 }, { - "x": 62.8, - "y": 50 + "x": 18.4, + "y": 5.2 }, { - "x": 63.6, - "y": 50 + "x": 18.8, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 64, - "y": 50 - }, - { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 } ] }, @@ -163,123 +158,119 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 372 + "width": 150, + "height": 278.8 }, { - "width": 188, - "height": 312.8 + "width": 150, + "height": 234.8 }, { - "width": 188, - "height": 246.8 - }, - { - "width": 188, + "width": 150, "height": 185.2 }, { - "width": 188, - "height": 133.6 + "width": 150, + "height": 138.8 }, { - "width": 188, - "height": 93.2 + "width": 150, + "height": 100.4 }, { - "width": 181.6, - "height": 62.8 + "width": 146.4, + "height": 69.6 }, { - "width": 174, - "height": 40.8 + "width": 138.4, + "height": 46.8 }, { - "width": 168.8, - "height": 22.4 + "width": 132.4, + "height": 28 }, { - "width": 165.2, - "height": 10 + "width": 128.4, + "height": 13.2 }, { - "width": 162.8, - "height": 2.4 + "width": 125.6, + "height": 4 }, { - "width": 161.2, + "width": 124, "height": 0 }, { - "width": 160.4, + "width": 122.8, "height": 0 }, { - "width": 160, + "width": 122.4, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 160, + "width": 122, "height": 0 } ] @@ -298,19 +289,18 @@ 1, 1, 1, - 1, - 0.91758585, - 0.72435355, - 0.52812576, - 0.3665868, - 0.24600428, - 0.16102076, - 0.103373945, - 0.06533456, - 0.04075712, - 0.025142312, - 0.015358448, - 0.0092999935, + 0.9762947, + 0.8118515, + 0.60931784, + 0.43090785, + 0.29299664, + 0.19368339, + 0.12531388, + 0.079705715, + 0.049988627, + 0.030979574, + 0.019001365, + 0.011548042, 0, 0, 0, diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json index 622c29eebfb4..7a02d369c7f2 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json +++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json @@ -19,9 +19,7 @@ 256, 272, 288, - 304, - 320, - 336 + 304 ], "features": [ { @@ -32,88 +30,80 @@ "type": "not_found" }, { - "x": 64, - "y": 50 + "x": 19.2, + "y": 5.2 }, { - "x": 59.2, - "y": 50 + "x": 15.6, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 8, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -125,88 +115,80 @@ "type": "not_found" }, { - "width": 160, + "width": 122, "height": 0 }, { - "width": 169.6, - "height": 6.8 - }, - { - "width": 188, - "height": 26.8 + "width": 129.2, + "height": 5.2 }, { - "width": 188, - "height": 95.6 + "width": 144.4, + "height": 16 }, { - "width": 188, - "height": 163.2 + "width": 150, + "height": 62 }, { - "width": 188, - "height": 222 + "width": 150, + "height": 118.4 }, { - "width": 188, - "height": 269.6 + "width": 150, + "height": 166 }, { - "width": 188, - "height": 307.2 + "width": 150, + "height": 204 }, { - "width": 188, - "height": 335.2 + "width": 150, + "height": 233.2 }, { - "width": 188, - "height": 356 + "width": 150, + "height": 254.4 }, { - "width": 188, - "height": 370.4 + "width": 150, + "height": 270 }, { - "width": 188, - "height": 380.8 + "width": 150, + "height": 280.8 }, { - "width": 188, - "height": 387.6 + "width": 150, + "height": 288 }, { - "width": 188, - "height": 392.4 + "width": 150, + "height": 292.8 }, { - "width": 188, - "height": 395.2 + "width": 150, + "height": 296 }, { - "width": 188, - "height": 397.2 + "width": 150, + "height": 298 }, { - "width": 188, - "height": 398 + "width": 150, + "height": 298.8 }, { - "width": 188, - "height": 398.8 + "width": 150, + "height": 299.2 }, { - "width": 188, - "height": 399.2 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 399.2 - }, - { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 } ] }, @@ -218,21 +200,19 @@ "type": "not_found" }, 0, - 0.05698657, - 0.24197984, - 0.44158113, - 0.6097554, - 0.73685503, - 0.8271309, - 0.8886989, - 0.9294886, - 0.9559254, - 0.97276413, - 0.98333716, - 0.98989624, - 1, - 1, - 1, + 0, + 0.0951103, + 0.2911651, + 0.48551244, + 0.6439433, + 0.76157355, + 0.8441935, + 0.9001033, + 0.9369305, + 0.96069145, + 0.97577035, + 0.98520935, + 0.9910494, 1, 1, 1, diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json index 59e8b51412b8..5ac06217d161 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json @@ -55,12 +55,7 @@ 832, 848, 864, - 880, - 896, - 912, - 928, - 944, - 960 + 880 ], "features": [ { @@ -68,248 +63,228 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50.4 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -318,247 +293,227 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 - }, - { - "width": 188, - "height": 400 - }, - { - "width": 188, - "height": 400 - }, - { - "width": 188, - "height": 393.2 - }, - { - "width": 188, - "height": 393.2 - }, - { - "width": 188, - "height": 386 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 379.6 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 372.8 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 366.8 + "width": 150, + "height": 292.8 }, { - "width": 188, - "height": 360.4 + "width": 150, + "height": 292.8 }, { - "width": 188, - "height": 354 + "width": 150, + "height": 286 }, { - "width": 188, - "height": 347.6 + "width": 150, + "height": 279.6 }, { - "width": 188, - "height": 341.2 + "width": 150, + "height": 273.2 }, { - "width": 188, - "height": 341.2 + "width": 150, + "height": 266.8 }, { - "width": 188, - "height": 334 + "width": 150, + "height": 260.4 }, { - "width": 188, - "height": 328 + "width": 150, + "height": 254 }, { - "width": 188, - "height": 321.6 + "width": 150, + "height": 247.6 }, { - "width": 188, - "height": 315.2 + "width": 150, + "height": 241.2 }, { - "width": 188, - "height": 308.8 + "width": 150, + "height": 241.2 }, { - "width": 188, - "height": 302.4 + "width": 150, + "height": 234.4 }, { - "width": 188, - "height": 296 + "width": 150, + "height": 228 }, { - "width": 188, - "height": 289.6 + "width": 150, + "height": 221.6 }, { - "width": 188, - "height": 289.6 + "width": 150, + "height": 215.2 }, { - "width": 188, - "height": 282.8 + "width": 150, + "height": 208.8 }, { - "width": 188, - "height": 276.4 + "width": 150, + "height": 202 }, { - "width": 188, - "height": 270 + "width": 150, + "height": 195.6 }, { - "width": 188, - "height": 263.6 + "width": 150, + "height": 189.2 }, { - "width": 188, - "height": 257.2 + "width": 150, + "height": 189.2 }, { - "width": 188, - "height": 250.8 + "width": 150, + "height": 182.8 }, { - "width": 188, - "height": 244.4 + "width": 150, + "height": 176.4 }, { - "width": 188, - "height": 238 + "width": 150, + "height": 170 }, { - "width": 188, - "height": 238 + "width": 150, + "height": 163.6 }, { - "width": 188, - "height": 231.2 + "width": 150, + "height": 157.2 }, { - "width": 188, - "height": 224.8 + "width": 150, + "height": 150.8 }, { - "width": 188, - "height": 218.4 + "width": 150, + "height": 144.4 }, { - "width": 188, - "height": 212 + "width": 150, + "height": 137.6 }, { - "width": 188, - "height": 212 + "width": 150, + "height": 137.6 }, { - "width": 188, - "height": 192.4 + "width": 150, + "height": 131.2 }, { - "width": 188, - "height": 159.6 + "width": 150, + "height": 124.8 }, { - "width": 188, - "height": 124.4 + "width": 150, + "height": 118.4 }, { - "width": 188, - "height": 92.8 + "width": 150, + "height": 112 }, { - "width": 188, - "height": 64.8 + "width": 150, + "height": 112 }, { - "width": 188, - "height": 44.4 + "width": 150, + "height": 99.2 }, { - "width": 188, - "height": 29.2 + "width": 150, + "height": 84.4 }, { - "width": 188, - "height": 18.4 + "width": 150, + "height": 70.8 }, { - "width": 188, - "height": 10.8 + "width": 150, + "height": 58 }, { - "width": 188, - "height": 5.6 + "width": 150, + "height": 46.4 }, { - "width": 188, - "height": 2.4 + "width": 150, + "height": 36.4 }, { - "width": 188, - "height": 0.4 + "width": 150, + "height": 28 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 20.8 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 15.6 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 11.2 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 8 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 5.6 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 3.6 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 2.4 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 1.2 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 0.8 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 0.4 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 } ] @@ -609,24 +564,19 @@ 1, 1, 1, - 1, - 1, - 0.9808927, - 0.8211168, - 0.61845565, - 0.43834114, - 0.29850912, - 0.19755232, - 0.12793064, - 0.08142871, - 0.051099956, - 0.031684637, - 0.019442618, - 0.011821032, - 0, - 0, - 0, - 0, + 0.99781144, + 0.87040234, + 0.6695792, + 0.48078007, + 0.33033127, + 0.22004372, + 0.1432175, + 0.09153092, + 0.057634592, + 0.035840213, + 0.022048414, + 0.013435662, + 0.008117795, 0 ] } diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json index 210ff0985e78..1cae67b3eba7 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json @@ -58,7 +58,8 @@ 880, 896, 912, - 928 + 928, + 944 ], "features": [ { @@ -66,240 +67,244 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50.8, - "y": 52 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 + }, + { + "x": 5.2, + "y": 5.2 } ] }, @@ -308,239 +313,243 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 390 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 390 + "width": 150, + "height": 297.6 }, { - "width": 188, - "height": 379.2 + "width": 150, + "height": 292.4 }, { - "width": 188, - "height": 371.2 + "width": 150, + "height": 287.6 }, { - "width": 188, - "height": 363.2 + "width": 150, + "height": 282.8 }, { - "width": 188, - "height": 355.2 + "width": 150, + "height": 278 }, { - "width": 188, - "height": 347.2 + "width": 150, + "height": 273.2 }, { - "width": 188, - "height": 339.2 + "width": 150, + "height": 268.4 }, { - "width": 188, - "height": 331.2 + "width": 150, + "height": 263.6 }, { - "width": 188, - "height": 323.2 + "width": 150, + "height": 258.8 }, { - "width": 188, - "height": 323.2 + "width": 150, + "height": 258.8 }, { - "width": 188, - "height": 314.8 + "width": 150, + "height": 253.6 }, { - "width": 188, - "height": 306.8 + "width": 150, + "height": 248.8 }, { - "width": 188, - "height": 298.8 + "width": 150, + "height": 244 }, { - "width": 188, - "height": 290.8 + "width": 150, + "height": 239.2 }, { - "width": 188, - "height": 282.8 + "width": 150, + "height": 234.4 }, { - "width": 188, - "height": 274.8 + "width": 150, + "height": 229.6 }, { - "width": 188, - "height": 266.8 + "width": 150, + "height": 224.8 }, { - "width": 188, - "height": 258.8 + "width": 150, + "height": 220 }, { - "width": 188, - "height": 258.8 + "width": 150, + "height": 220 }, { - "width": 188, - "height": 250.4 + "width": 150, + "height": 214.8 }, { - "width": 188, - "height": 242.4 + "width": 150, + "height": 210 }, { - "width": 188, - "height": 234.4 + "width": 150, + "height": 205.2 }, { - "width": 188, - "height": 226.4 + "width": 150, + "height": 200.4 }, { - "width": 188, - "height": 218.4 + "width": 150, + "height": 195.6 }, { - "width": 188, - "height": 210.4 + "width": 150, + "height": 190.8 }, { - "width": 188, - "height": 202.4 + "width": 150, + "height": 186 }, { - "width": 188, - "height": 194.4 + "width": 150, + "height": 181.2 }, { - "width": 188, - "height": 194.4 + "width": 150, + "height": 181.2 }, { - "width": 188, - "height": 185.6 + "width": 150, + "height": 176.4 }, { - "width": 188, - "height": 178 + "width": 150, + "height": 171.6 }, { - "width": 188, - "height": 170 + "width": 150, + "height": 166.8 }, { - "width": 188, + "width": 150, "height": 161.6 }, { - "width": 188, + "width": 150, "height": 161.6 }, { - "width": 188, - "height": 144.8 + "width": 150, + "height": 147.2 }, { - "width": 188, - "height": 118.8 + "width": 150, + "height": 122 }, { - "width": 188, - "height": 92 + "width": 150, + "height": 95.2 }, { - "width": 188, - "height": 68 + "width": 150, + "height": 70.8 }, { - "width": 188, - "height": 49.6 + "width": 150, + "height": 51.6 }, { - "width": 188, - "height": 35.2 + "width": 150, + "height": 36.8 }, { - "width": 188, - "height": 24.4 + "width": 150, + "height": 25.6 }, { - "width": 188, - "height": 16.4 + "width": 150, + "height": 17.2 }, { - "width": 188, - "height": 10.4 + "width": 150, + "height": 11.2 }, { - "width": 188, - "height": 6.4 + "width": 150, + "height": 6.8 }, { - "width": 188, - "height": 3.6 + "width": 150, + "height": 4 }, { - "width": 188, - "height": 1.6 + "width": 150, + "height": 2 }, { - "width": 188, - "height": 0.4 + "width": 150, + "height": 0.8 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, + "height": 0 + }, + { + "width": 150, "height": 0 } ] @@ -592,19 +601,20 @@ 1, 1, 1, - 0.9967737, - 0.86538374, - 0.66414475, - 0.47619528, - 0.32686388, - 0.21757984, - 0.14153665, - 0.09041709, - 0.05691254, - 0.035380244, - 0.02175957, - 0.01325649, - 0.008007765, + 0.99979615, + 0.8860379, + 0.6869267, + 0.4955439, + 0.34154767, + 0.22803628, + 0.14868057, + 0.09515619, + 0.059987247, + 0.037340224, + 0.02299112, + 0.01402092, + 0.008477271, + 0, 0, 0, 0 diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json index d186df22dda0..1bf6a62d02af 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json @@ -68,200 +68,200 @@ "type": "not_found" }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -279,200 +279,200 @@ "type": "not_found" }, { - "width": 188, + "width": 150, "height": 1.6 }, { - "width": 188, + "width": 150, "height": 1.6 }, { - "width": 188, + "width": 150, "height": 3.2 }, { - "width": 188, + "width": 150, "height": 4.8 }, { - "width": 188, + "width": 150, "height": 6.4 }, { - "width": 188, + "width": 150, "height": 8 }, { - "width": 188, + "width": 150, "height": 9.6 }, { - "width": 188, + "width": 150, "height": 11.2 }, { - "width": 188, + "width": 150, "height": 12.8 }, { - "width": 188, + "width": 150, "height": 14.4 }, { - "width": 188, + "width": 150, "height": 14.4 }, { - "width": 188, + "width": 150, "height": 16.4 }, { - "width": 188, + "width": 150, "height": 18 }, { - "width": 188, + "width": 150, "height": 19.6 }, { - "width": 188, - "height": 21.2 + "width": 150, + "height": 20.8 }, { - "width": 188, + "width": 150, "height": 22.8 }, { - "width": 188, + "width": 150, "height": 24.4 }, { - "width": 188, + "width": 150, "height": 26 }, { - "width": 188, + "width": 150, "height": 27.6 }, { - "width": 188, + "width": 150, "height": 27.6 }, { - "width": 188, + "width": 150, "height": 29.2 }, { - "width": 188, + "width": 150, "height": 30.8 }, { - "width": 188, + "width": 150, "height": 32.4 }, { - "width": 188, + "width": 150, "height": 34 }, { - "width": 188, + "width": 150, "height": 40.4 }, { - "width": 188, + "width": 150, "height": 52.4 }, { - "width": 188, + "width": 150, "height": 64.8 }, { - "width": 188, + "width": 150, "height": 83.2 }, { - "width": 188, + "width": 150, "height": 96 }, { - "width": 188, + "width": 150, "height": 114.8 }, { - "width": 188, + "width": 150, "height": 132 }, { - "width": 188, + "width": 150, "height": 148 }, { - "width": 188, + "width": 150, "height": 162 }, { - "width": 188, + "width": 150, "height": 168.4 }, { - "width": 188, - "height": 192.8 + "width": 150, + "height": 186 }, { - "width": 188, - "height": 229.6 + "width": 150, + "height": 208 }, { - "width": 188, - "height": 268 + "width": 150, + "height": 229.6 }, { - "width": 188, - "height": 302 + "width": 150, + "height": 248.4 }, { - "width": 188, - "height": 330 + "width": 150, + "height": 263.2 }, { - "width": 188, - "height": 351.6 + "width": 150, + "height": 274.8 }, { - "width": 188, - "height": 367.6 + "width": 150, + "height": 283.2 }, { - "width": 188, - "height": 379.2 + "width": 150, + "height": 289.2 }, { - "width": 188, - "height": 387.2 + "width": 150, + "height": 293.6 }, { - "width": 188, - "height": 392.4 + "width": 150, + "height": 296 }, { - "width": 188, - "height": 395.6 + "width": 150, + "height": 298 }, { - "width": 188, - "height": 398 + "width": 150, + "height": 298.8 }, { - "width": 188, - "height": 398.8 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 } ] }, @@ -494,12 +494,12 @@ 0, 0, 0.0067873597, - 0.0612576, - 0.19080025, + 0.06125766, + 0.19080031, 0.39327443, 0.5711931, - 0.70855826, - 0.8074064, + 0.7085583, + 0.8074065, 0.8754226, 0.9207788, 0.95032376, diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json index a9c24fa87089..ca87bc28c45d 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json @@ -39,9 +39,7 @@ 576, 592, 608, - 624, - 640, - 656 + 624 ], "features": [ { @@ -49,172 +47,164 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50.4, - "y": 50.8 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -223,171 +213,163 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 389.6 + "width": 150, + "height": 288.8 }, { - "width": 188, - "height": 378.8 + "width": 150, + "height": 278.8 }, { - "width": 188, - "height": 366 + "width": 150, + "height": 266 }, { - "width": 188, - "height": 352 + "width": 150, + "height": 252 }, { - "width": 188, - "height": 352 + "width": 150, + "height": 252 }, { - "width": 188, - "height": 316.8 + "width": 150, + "height": 224 }, { - "width": 188, - "height": 261.2 + "width": 150, + "height": 183.2 }, { - "width": 188, - "height": 202.8 + "width": 150, + "height": 141.6 }, { - "width": 188, - "height": 150.8 + "width": 150, + "height": 104.4 }, { - "width": 188, - "height": 107.6 + "width": 150, + "height": 72.4 }, { - "width": 188, - "height": 71.2 + "width": 150, + "height": 46.4 }, { - "width": 188, - "height": 41.6 + "width": 150, + "height": 28 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 15.6 }, { - "width": 188, - "height": 8.4 + "width": 150, + "height": 7.2 }, { - "width": 188, - "height": 0.4 - }, - { - "width": 188, - "height": 0 + "width": 150, + "height": 2 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, - "height": 0 - }, - { - "width": 188, + "width": 150, "height": 0 } ] @@ -418,21 +400,19 @@ 1, 1, 1, - 1, - 0.9833227, - 0.8263634, - 0.623688, - 0.44261706, - 0.3016883, - 0.1997872, - 0.12944388, - 0.08242595, - 0.051743627, - 0.032093227, - 0.019698441, - 0.0119793415, - 0, - 0, + 0.99532944, + 0.8594856, + 0.65783304, + 0.47089338, + 0.32286334, + 0.21474117, + 0.139602, + 0.089136004, + 0.056082606, + 0.03485179, + 0.02142787, + 0.013050735, + 0.007881463, 0, 0, 0, diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json index f9279f1fae5c..98519db9e848 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json @@ -66,112 +66,112 @@ "type": "not_found" }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -204,112 +204,112 @@ "type": "not_found" }, { - "width": 188, + "width": 150, "height": 2 }, { - "width": 188, + "width": 150, "height": 4.4 }, { - "width": 188, + "width": 150, "height": 6.8 }, { - "width": 188, + "width": 150, "height": 10 }, { - "width": 188, + "width": 150, "height": 13.2 }, { - "width": 188, + "width": 150, "height": 16.8 }, { - "width": 188, + "width": 150, "height": 16.8 }, { - "width": 188, - "height": 25.2 + "width": 150, + "height": 23.6 }, { - "width": 188, - "height": 53.2 + "width": 150, + "height": 32.8 }, { - "width": 188, - "height": 119.6 + "width": 150, + "height": 76.8 }, { - "width": 188, - "height": 182 + "width": 150, + "height": 123.6 }, { - "width": 188, - "height": 235.6 + "width": 150, + "height": 164.8 }, { - "width": 188, - "height": 279.2 + "width": 150, + "height": 198.4 }, { - "width": 188, - "height": 313.2 + "width": 150, + "height": 225.6 }, { - "width": 188, - "height": 338.8 + "width": 150, + "height": 246.4 }, { - "width": 188, - "height": 357.6 + "width": 150, + "height": 262 }, { - "width": 188, - "height": 371.2 + "width": 150, + "height": 273.2 }, { - "width": 188, - "height": 380.8 + "width": 150, + "height": 281.6 }, { - "width": 188, - "height": 387.6 + "width": 150, + "height": 287.6 }, { - "width": 188, - "height": 392 + "width": 150, + "height": 292 }, { - "width": 188, - "height": 395.2 + "width": 150, + "height": 294.8 }, { - "width": 188, - "height": 396.8 + "width": 150, + "height": 296.4 }, { - "width": 188, - "height": 398 + "width": 150, + "height": 297.6 }, { - "width": 188, - "height": 398.8 + "width": 150, + "height": 298.4 }, { - "width": 188, - "height": 399.2 + "width": 150, + "height": 299.2 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 } ] }, diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json index 2504e57a927b..850cee9130d0 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json @@ -68,7 +68,10 @@ 1040, 1056, 1072, - 1088 + 1088, + 1104, + 1120, + 1136 ], "features": [ { @@ -85,267 +88,280 @@ "type": "not_found" }, { - "type": "not_found" + "x": 5.2, + "y": 5.2 + }, + { + "x": 5.2, + "y": 5.2 + }, + { + "x": 5.2, + "y": 5.2 + }, + { + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -363,266 +379,279 @@ "type": "not_found" }, { - "type": "not_found" + "width": 150, + "height": 2.8 }, { - "width": 188, - "height": 1.6 + "width": 150, + "height": 4.8 }, { - "width": 188, - "height": 2.8 + "width": 150, + "height": 6.8 }, { - "width": 188, - "height": 4 + "width": 150, + "height": 8.4 }, { - "width": 188, - "height": 5.2 + "width": 150, + "height": 10.4 }, { - "width": 188, - "height": 6.4 + "width": 150, + "height": 12.4 }, { - "width": 188, - "height": 7.6 + "width": 150, + "height": 14 }, { - "width": 188, - "height": 8.8 + "width": 150, + "height": 16 }, { - "width": 188, - "height": 10 + "width": 150, + "height": 17.6 }, { - "width": 188, - "height": 10.8 + "width": 150, + "height": 19.2 }, { - "width": 188, - "height": 12 + "width": 150, + "height": 20.8 }, { - "width": 188, - "height": 12.8 + "width": 150, + "height": 22.4 }, { - "width": 188, - "height": 13.6 + "width": 150, + "height": 24 }, { - "width": 188, - "height": 14.8 + "width": 150, + "height": 25.6 }, { - "width": 188, - "height": 15.6 + "width": 150, + "height": 26.8 }, { - "width": 188, - "height": 16.4 + "width": 150, + "height": 28 }, { - "width": 188, - "height": 17.2 + "width": 150, + "height": 29.2 }, { - "width": 188, - "height": 17.6 + "width": 150, + "height": 30.4 }, { - "width": 188, - "height": 18.4 + "width": 150, + "height": 31.6 }, { - "width": 188, - "height": 19.2 + "width": 150, + "height": 32.4 }, { - "width": 188, - "height": 19.6 + "width": 150, + "height": 33.2 }, { - "width": 188, - "height": 20 + "width": 150, + "height": 34 }, { - "width": 188, - "height": 20.4 + "width": 150, + "height": 36.8 }, { - "width": 188, - "height": 20.8 + "width": 150, + "height": 42.4 }, { - "width": 188, - "height": 21.2 + "width": 150, + "height": 50.8 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 64 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 78 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 91.2 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 102.4 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 112.4 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 120 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 126 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 130 }, { - "width": 188, - "height": 21.2 + "width": 150, + "height": 132.8 }, { - "width": 188, - "height": 20.8 + "width": 150, + "height": 134 }, { - "width": 188, - "height": 20.4 + "width": 150, + "height": 134 }, { - "width": 188, - "height": 20 + "width": 150, + "height": 133.2 }, { - "width": 188, - "height": 19.6 + "width": 150, + "height": 131.2 }, { - "width": 188, - "height": 19.2 + "width": 150, + "height": 128.8 }, { - "width": 188, - "height": 18.4 + "width": 150, + "height": 125.2 }, { - "width": 188, - "height": 17.6 + "width": 150, + "height": 121.6 }, { - "width": 188, - "height": 17.2 + "width": 150, + "height": 117.6 }, { - "width": 188, - "height": 16.4 + "width": 150, + "height": 112.8 }, { - "width": 188, - "height": 15.6 + "width": 150, + "height": 108 }, { - "width": 188, - "height": 14.8 + "width": 150, + "height": 102.4 }, { - "width": 188, - "height": 13.6 + "width": 150, + "height": 96.4 }, { - "width": 188, - "height": 12.8 + "width": 150, + "height": 91.2 }, { - "width": 188, - "height": 12 + "width": 150, + "height": 88 }, { - "width": 188, - "height": 10.8 + "width": 150, + "height": 81.6 }, { - "width": 188, - "height": 10 + "width": 150, + "height": 70.8 }, { - "width": 188, - "height": 8.8 + "width": 150, + "height": 59.2 }, { - "width": 188, - "height": 7.6 + "width": 150, + "height": 48 }, { - "width": 188, - "height": 6.4 + "width": 150, + "height": 38.4 }, { - "width": 188, - "height": 5.2 + "width": 150, + "height": 30 }, { - "width": 188, - "height": 4 + "width": 150, + "height": 22.8 }, { - "width": 188, - "height": 2.8 + "width": 150, + "height": 17.2 }, { - "width": 188, - "height": 1.6 + "width": 150, + "height": 12.4 }, { - "width": 188, - "height": 0.4 + "width": 150, + "height": 9.2 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 6.4 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 4.4 }, { - "width": 188, - "height": 0 + "width": 150, + "height": 2.8 + }, + { + "width": 150, + "height": 1.6 + }, + { + "width": 150, + "height": 1.2 + }, + { + "width": 150, + "height": 0.4 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 } ] @@ -640,26 +669,27 @@ { "type": "not_found" }, - { - "type": "not_found" - }, - 0, - 0, 0, 0, - 0.012518823, - 0.0741024, - 0.2254293, - 0.42628878, - 0.5976641, - 0.7280312, - 0.82100236, - 0.8845844, - 0.9267946, - 0.95419544, - 0.9716705, - 0.98265487, - 0.98947525, + 0.0066464543, + 0.059778452, + 0.1875459, + 0.39009166, + 0.5686131, + 0.70664865, + 0.8060679, + 0.87451804, + 0.92018366, + 0.94994, + 0.9689752, + 0.9809703, + 0.98843443, + 1, + 1, + 1, + 1, + 1, + 1, 1, 1, 1, @@ -695,19 +725,19 @@ 1, 1, 1, - 0.9944124, - 0.9417388, - 0.8184184, - 0.6157812, - 0.4361611, - 0.2968906, - 0.19641554, - 0.12716137, - 0.080921985, - 0.050773025, - 0.03147719, - 0.019312752, - 0.011740655 + 0.98828065, + 0.9288363, + 0.7806658, + 0.57941735, + 0.40687433, + 0.27529213, + 0.18131107, + 0.11697123, + 0.074225225, + 0.046460062, + 0.028744182, + 0.017604083, + 0.010684598 ] } ] diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json index 86fac739372e..afa005ac421e 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json @@ -27,8 +27,7 @@ 384, 400, 416, - 432, - 448 + 432 ], "features": [ { @@ -36,120 +35,116 @@ "type": "dpOffset", "data_points": [ { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 - }, - { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 } ] }, @@ -158,119 +153,115 @@ "type": "dpSize", "data_points": [ { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 400 + "width": 150, + "height": 300 }, { - "width": 188, - "height": 372 + "width": 150, + "height": 278.8 }, { - "width": 188, - "height": 312.8 + "width": 150, + "height": 234.8 }, { - "width": 188, - "height": 246.8 - }, - { - "width": 188, + "width": 150, "height": 185.2 }, { - "width": 188, - "height": 133.6 + "width": 150, + "height": 138.8 }, { - "width": 188, - "height": 93.2 + "width": 150, + "height": 100.4 }, { - "width": 188, - "height": 58.8 + "width": 150, + "height": 66.8 }, { - "width": 188, - "height": 34.4 + "width": 150, + "height": 41.6 }, { - "width": 188, - "height": 18 + "width": 150, + "height": 23.6 }, { - "width": 188, - "height": 7.6 + "width": 150, + "height": 12 }, { - "width": 188, - "height": 0.8 + "width": 150, + "height": 4.4 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, + "width": 150, "height": 0 } ] @@ -289,19 +280,18 @@ 1, 1, 1, - 1, - 0.91758585, - 0.72435355, - 0.52812576, - 0.3665868, - 0.24600428, - 0.16102076, - 0.103373945, - 0.06533456, - 0.04075712, - 0.025142312, - 0.015358448, - 0.0092999935, + 0.9762947, + 0.8118515, + 0.60931784, + 0.43090785, + 0.29299664, + 0.19368339, + 0.12531388, + 0.079705715, + 0.049988627, + 0.030979574, + 0.019001365, + 0.011548042, 0, 0, 0, diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json index ad282f216f8f..317d4804fa52 100644 --- a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json +++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json @@ -21,7 +21,8 @@ 288, 304, 320, - 336 + 336, + 352 ], "features": [ { @@ -32,88 +33,92 @@ "type": "not_found" }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 }, { - "x": 50, - "y": 50 + "x": 5.2, + "y": 5.2 + }, + { + "x": 5.2, + "y": 5.2 } ] }, @@ -125,88 +130,92 @@ "type": "not_found" }, { - "width": 188, + "width": 150, "height": 0 }, { - "width": 188, - "height": 6.8 + "width": 150, + "height": 5.2 }, { - "width": 188, - "height": 21.6 + "width": 150, + "height": 16 }, { - "width": 188, - "height": 52.8 + "width": 150, + "height": 28.4 }, { - "width": 188, - "height": 129.6 + "width": 150, + "height": 63.6 }, { - "width": 188, - "height": 196.4 + "width": 150, + "height": 116.4 }, { - "width": 188, - "height": 250.4 + "width": 150, + "height": 161.2 }, { - "width": 188, - "height": 293.2 + "width": 150, + "height": 197.2 }, { - "width": 188, - "height": 325.2 + "width": 150, + "height": 225.2 }, { - "width": 188, - "height": 348.8 + "width": 150, + "height": 246.8 }, { - "width": 188, - "height": 365.6 + "width": 150, + "height": 262.4 }, { - "width": 188, - "height": 377.2 + "width": 150, + "height": 274 }, { - "width": 188, - "height": 385.6 + "width": 150, + "height": 282.4 }, { - "width": 188, - "height": 391.2 + "width": 150, + "height": 288.4 }, { - "width": 188, - "height": 394.8 + "width": 150, + "height": 292.4 }, { - "width": 188, - "height": 396.8 + "width": 150, + "height": 294.8 }, { - "width": 188, - "height": 398 + "width": 150, + "height": 296.4 }, { - "width": 188, - "height": 398.8 + "width": 150, + "height": 297.6 }, { - "width": 188, - "height": 399.2 + "width": 150, + "height": 298.4 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.2 }, { - "width": 188, - "height": 399.6 + "width": 150, + "height": 299.6 + }, + { + "width": 150, + "height": 299.6 } ] }, @@ -218,18 +227,19 @@ "type": "not_found" }, 0, - 0.05698657, - 0.24197984, - 0.44158113, - 0.6097554, - 0.73685503, - 0.8271309, - 0.8886989, - 0.9294886, - 0.9559254, - 0.97276413, - 0.98333716, - 0.98989624, + 0, + 0.0951103, + 0.2911651, + 0.48551244, + 0.6439433, + 0.76157355, + 0.8441935, + 0.9001033, + 0.9369305, + 0.96069145, + 0.97577035, + 0.98520935, + 0.9910494, 1, 1, 1, diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt index ed73d100dc6b..1bc83e0401bf 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt @@ -111,10 +111,12 @@ class ContentRevealTest(private val isFloating: Boolean) { assertVerticalContainerRevealMotion( GestureRevealMotion(SceneClosed) { val gestureDurationMillis = 1000L + // detach position for the floating container is larger + val gestureHeight = if (isFloating) 160.dp.toPx() else 100.dp.toPx() swipe( curve = { val progress = it / gestureDurationMillis.toFloat() - val y = sin(progress * Math.PI).toFloat() * 100.dp.toPx() + val y = sin(progress * Math.PI).toFloat() * gestureHeight Offset(centerX, y) }, gestureDurationMillis, @@ -159,7 +161,7 @@ class ContentRevealTest(private val isFloating: Boolean) { fun verticalReveal_gesture_dragHalfClose() { assertVerticalContainerRevealMotion( GestureRevealMotion(SceneOpen) { - swipeUp(350.dp.toPx(), 100.dp.toPx(), durationMillis = 500) + swipeUp(250.dp.toPx(), 100.dp.toPx(), durationMillis = 500) }, "verticalReveal_gesture_dragHalfClose", ) @@ -251,9 +253,9 @@ class ContentRevealTest(private val isFloating: Boolean) { SceneTransitionLayoutForTesting( state, modifier = - Modifier.padding(50.dp) + Modifier.padding(5.dp) .background(Color.Yellow) - .size(ContainerSize.width, ContainerSize.height + 200.dp) + .size(ContainerSize.width, ContainerSize.height + 100.dp) .testTag("stl"), ) { scene( @@ -298,7 +300,7 @@ class ContentRevealTest(private val isFloating: Boolean) { companion object { @get:Parameters @JvmStatic val parameterValues = listOf(true, false) - val ContainerSize = DpSize(200.dp, 400.dp) + val ContainerSize = DpSize(150.dp, 300.dp) val FlingVelocity = 1000.dp // dp/sec diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt index e4a87ba3a26b..7d9a32b3948a 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt @@ -58,17 +58,24 @@ class ElementStateAccessTest { assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(1f, 1f)) } + at(16) { + val semanticNode = onElement(TestElements.Foo).fetchSemanticsNode() + assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0.75f) + assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0.75f, 0.75f)) + } + at(32) { val semanticNode = onElement(TestElements.Foo).fetchSemanticsNode() assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0.5f) assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0.5f, 0.5f)) } - at(64) { + at(48) { val semanticNode = onElement(TestElements.Foo).fetchSemanticsNode() - assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0f) - assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0f, 0f)) + assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0.25f) + assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0.25f, 0.25f)) } + after { onElement(TestElements.Foo).assertDoesNotExist() } } } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt index 37acbe261f76..5f71b19fbc3f 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt @@ -22,10 +22,10 @@ import com.android.app.animation.Interpolators import com.android.systemui.log.core.Logger import com.android.systemui.plugins.clocks.AlarmData import com.android.systemui.plugins.clocks.ClockAnimations +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockEvents import com.android.systemui.plugins.clocks.ClockFaceConfig import com.android.systemui.plugins.clocks.ClockFaceEvents -import com.android.systemui.plugins.clocks.ClockFontAxisSetting import com.android.systemui.plugins.clocks.ThemeConfig import com.android.systemui.plugins.clocks.WeatherData import com.android.systemui.plugins.clocks.ZenData @@ -111,7 +111,7 @@ class ComposedDigitalLayerController(private val clockCtx: ClockContext) : override fun onZenDataChanged(data: ZenData) {} - override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) { + override fun onFontAxesChanged(axes: ClockAxisStyle) { view.updateAxes(axes) } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt index bc4bdf4243cb..3cfa78d17fe7 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt @@ -26,6 +26,7 @@ import com.android.systemui.customization.R import com.android.systemui.log.core.MessageBuffer import com.android.systemui.plugins.clocks.AlarmData import com.android.systemui.plugins.clocks.ClockAnimations +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockConfig import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockEventListener @@ -33,7 +34,6 @@ import com.android.systemui.plugins.clocks.ClockEvents import com.android.systemui.plugins.clocks.ClockFaceConfig import com.android.systemui.plugins.clocks.ClockFaceController import com.android.systemui.plugins.clocks.ClockFaceEvents -import com.android.systemui.plugins.clocks.ClockFontAxisSetting import com.android.systemui.plugins.clocks.ClockMessageBuffers import com.android.systemui.plugins.clocks.ClockSettings import com.android.systemui.plugins.clocks.DefaultClockFaceLayout @@ -232,7 +232,7 @@ class DefaultClockController( override fun onZenDataChanged(data: ZenData) {} - override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) {} + override fun onFontAxesChanged(axes: ClockAxisStyle) {} } open inner class DefaultClockAnimations( diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt index c3935e68ca04..d778bc04ab8e 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt @@ -20,6 +20,8 @@ import android.os.Vibrator import android.view.LayoutInflater import com.android.systemui.customization.R import com.android.systemui.log.core.MessageBuffer +import com.android.systemui.plugins.clocks.AxisPresetConfig +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge import com.android.systemui.plugins.clocks.ClockLogger @@ -28,7 +30,7 @@ import com.android.systemui.plugins.clocks.ClockMetadata import com.android.systemui.plugins.clocks.ClockPickerConfig import com.android.systemui.plugins.clocks.ClockProvider import com.android.systemui.plugins.clocks.ClockSettings -import com.android.systemui.shared.clocks.FlexClockController.Companion.AXIS_PRESETS +import com.android.systemui.shared.clocks.FlexClockController.Companion.buildPresetGroup import com.android.systemui.shared.clocks.FlexClockController.Companion.getDefaultAxes private val TAG = DefaultClockProvider::class.simpleName @@ -80,7 +82,7 @@ class DefaultClockProvider( return if (isClockReactiveVariantsEnabled) { val buffers = messageBuffers ?: ClockMessageBuffers(ClockLogger.DEFAULT_MESSAGE_BUFFER) val fontAxes = getDefaultAxes(settings).merge(settings.axes) - val clockSettings = settings.copy(axes = fontAxes.map { it.toSetting() }) + val clockSettings = settings.copy(axes = ClockAxisStyle(fontAxes)) val typefaceCache = TypefaceCache(buffers.infraMessageBuffer, NUM_CLOCK_FONT_ANIMATION_STEPS) { FLEX_TYPEFACE @@ -106,17 +108,35 @@ class DefaultClockProvider( throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG") } - return ClockPickerConfig( - settings.clockId ?: DEFAULT_CLOCK_ID, - resources.getString(R.string.clock_default_name), - resources.getString(R.string.clock_default_description), - resources.getDrawable(R.drawable.clock_default_thumbnail, null), - isReactiveToTone = true, - axes = - if (!isClockReactiveVariantsEnabled) emptyList() - else getDefaultAxes(settings).merge(settings.axes), - axisPresets = if (!isClockReactiveVariantsEnabled) emptyList() else AXIS_PRESETS, - ) + if (!isClockReactiveVariantsEnabled) { + return ClockPickerConfig( + settings.clockId ?: DEFAULT_CLOCK_ID, + resources.getString(R.string.clock_default_name), + resources.getString(R.string.clock_default_description), + resources.getDrawable(R.drawable.clock_default_thumbnail, null), + isReactiveToTone = true, + axes = emptyList(), + presetConfig = null, + ) + } else { + val fontAxes = getDefaultAxes(settings).merge(settings.axes) + return ClockPickerConfig( + settings.clockId ?: DEFAULT_CLOCK_ID, + resources.getString(R.string.clock_default_name), + resources.getString(R.string.clock_default_description), + resources.getDrawable(R.drawable.clock_default_thumbnail, null), + isReactiveToTone = true, + axes = fontAxes, + presetConfig = + AxisPresetConfig( + listOf( + buildPresetGroup(resources, isRound = true), + buildPresetGroup(resources, isRound = false), + ) + ) + .let { cfg -> cfg.copy(current = cfg.findStyle(ClockAxisStyle(fontAxes))) }, + ) + } } companion object { diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt index 5acd4468fe92..96c3ac75587e 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt @@ -16,20 +16,24 @@ package com.android.systemui.shared.clocks +import android.content.res.Resources import com.android.systemui.animation.GSFAxes import com.android.systemui.customization.R import com.android.systemui.plugins.clocks.AlarmData +import com.android.systemui.plugins.clocks.AxisPresetConfig import com.android.systemui.plugins.clocks.AxisType +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockConfig import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockEventListener import com.android.systemui.plugins.clocks.ClockEvents import com.android.systemui.plugins.clocks.ClockFontAxis import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge -import com.android.systemui.plugins.clocks.ClockFontAxisSetting import com.android.systemui.plugins.clocks.ClockSettings import com.android.systemui.plugins.clocks.WeatherData import com.android.systemui.plugins.clocks.ZenData +import com.android.systemui.shared.clocks.FontUtils.put +import com.android.systemui.shared.clocks.FontUtils.toClockAxis import com.android.systemui.shared.clocks.view.FlexClockView import java.io.PrintWriter import java.util.Locale @@ -96,8 +100,8 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController largeClock.events.onZenDataChanged(data) } - override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) { - val fontAxes = getDefaultAxes(clockCtx.settings).merge(axes).map { it.toSetting() } + override fun onFontAxesChanged(axes: ClockAxisStyle) { + val fontAxes = ClockAxisStyle(getDefaultAxes(clockCtx.settings).merge(axes)) smallClock.events.onFontAxesChanged(fontAxes) largeClock.events.onFontAxesChanged(fontAxes) } @@ -162,66 +166,46 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController ), ) - private val LEGACY_FLEX_SETTINGS = - listOf( - GSFAxes.WEIGHT.toClockAxisSetting(600f), - GSFAxes.WIDTH.toClockAxisSetting(100f), - GSFAxes.ROUND.toClockAxisSetting(100f), - GSFAxes.SLANT.toClockAxisSetting(0f), - ) + private val LEGACY_FLEX_SETTINGS = ClockAxisStyle { + put(GSFAxes.WEIGHT, 600f) + put(GSFAxes.WIDTH, 100f) + put(GSFAxes.ROUND, 100f) + put(GSFAxes.SLANT, 0f) + } - val AXIS_PRESETS = - listOf( - FONT_AXES.map { it.toSetting() }, - LEGACY_FLEX_SETTINGS, - listOf( // Porcelain - GSFAxes.WEIGHT.toClockAxisSetting(500f), - GSFAxes.WIDTH.toClockAxisSetting(100f), - GSFAxes.ROUND.toClockAxisSetting(0f), - GSFAxes.SLANT.toClockAxisSetting(0f), - ), - listOf( // Midnight - GSFAxes.WEIGHT.toClockAxisSetting(300f), - GSFAxes.WIDTH.toClockAxisSetting(100f), - GSFAxes.ROUND.toClockAxisSetting(100f), - GSFAxes.SLANT.toClockAxisSetting(-10f), - ), - listOf( // Sterling - GSFAxes.WEIGHT.toClockAxisSetting(1000f), - GSFAxes.WIDTH.toClockAxisSetting(100f), - GSFAxes.ROUND.toClockAxisSetting(0f), - GSFAxes.SLANT.toClockAxisSetting(0f), - ), - listOf( // Smoky Green - GSFAxes.WEIGHT.toClockAxisSetting(150f), - GSFAxes.WIDTH.toClockAxisSetting(50f), - GSFAxes.ROUND.toClockAxisSetting(0f), - GSFAxes.SLANT.toClockAxisSetting(0f), - ), - listOf( // Iris - GSFAxes.WEIGHT.toClockAxisSetting(500f), - GSFAxes.WIDTH.toClockAxisSetting(100f), - GSFAxes.ROUND.toClockAxisSetting(100f), - GSFAxes.SLANT.toClockAxisSetting(0f), - ), - listOf( // Margarita - GSFAxes.WEIGHT.toClockAxisSetting(300f), - GSFAxes.WIDTH.toClockAxisSetting(30f), - GSFAxes.ROUND.toClockAxisSetting(100f), - GSFAxes.SLANT.toClockAxisSetting(-10f), - ), - listOf( // Raspberry - GSFAxes.WEIGHT.toClockAxisSetting(700f), - GSFAxes.WIDTH.toClockAxisSetting(140f), - GSFAxes.ROUND.toClockAxisSetting(100f), - GSFAxes.SLANT.toClockAxisSetting(-7f), - ), - listOf( // Ultra Blue - GSFAxes.WEIGHT.toClockAxisSetting(850f), - GSFAxes.WIDTH.toClockAxisSetting(130f), - GSFAxes.ROUND.toClockAxisSetting(0f), - GSFAxes.SLANT.toClockAxisSetting(0f), - ), + private val PRESET_COUNT = 8 + private val PRESET_WIDTH_INIT = 30f + private val PRESET_WIDTH_STEP = 12.5f + private val PRESET_WEIGHT_INIT = 800f + private val PRESET_WEIGHT_STEP = -100f + private val BASE_PRESETS: List<ClockAxisStyle> = run { + val presets = mutableListOf<ClockAxisStyle>() + var weight = PRESET_WEIGHT_INIT + var width = PRESET_WIDTH_INIT + for (i in 1..PRESET_COUNT) { + presets.add( + ClockAxisStyle { + put(GSFAxes.WEIGHT, weight) + put(GSFAxes.WIDTH, width) + put(GSFAxes.ROUND, 0f) + put(GSFAxes.SLANT, 0f) + } + ) + + weight += PRESET_WEIGHT_STEP + width += PRESET_WIDTH_STEP + } + + return@run presets + } + + fun buildPresetGroup(resources: Resources, isRound: Boolean): AxisPresetConfig.Group { + val round = if (isRound) GSFAxes.ROUND.maxValue else GSFAxes.ROUND.minValue + return AxisPresetConfig.Group( + presets = BASE_PRESETS.map { it.copy { put(GSFAxes.ROUND, round) } }, + // TODO(b/395647577): Placeholder Icon; Replace or remove + icon = resources.getDrawable(R.drawable.clock_default_thumbnail, null), ) + } } } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt index 578a489c68c6..171a68f72e20 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt @@ -25,16 +25,18 @@ import com.android.systemui.animation.GSFAxes import com.android.systemui.customization.R import com.android.systemui.plugins.clocks.AlarmData import com.android.systemui.plugins.clocks.ClockAnimations +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockEvents import com.android.systemui.plugins.clocks.ClockFaceConfig import com.android.systemui.plugins.clocks.ClockFaceController import com.android.systemui.plugins.clocks.ClockFaceEvents import com.android.systemui.plugins.clocks.ClockFaceLayout -import com.android.systemui.plugins.clocks.ClockFontAxisSetting import com.android.systemui.plugins.clocks.DefaultClockFaceLayout import com.android.systemui.plugins.clocks.ThemeConfig import com.android.systemui.plugins.clocks.WeatherData import com.android.systemui.plugins.clocks.ZenData +import com.android.systemui.shared.clocks.FontUtils.get +import com.android.systemui.shared.clocks.FontUtils.set import com.android.systemui.shared.clocks.ViewUtils.computeLayoutDiff import com.android.systemui.shared.clocks.view.FlexClockView import com.android.systemui.shared.clocks.view.HorizontalAlignment @@ -129,17 +131,10 @@ class FlexClockFaceController(clockCtx: ClockContext, private val isLargeClock: layerController.faceEvents.onThemeChanged(theme) } - override fun onFontAxesChanged(settings: List<ClockFontAxisSetting>) { - var axes = settings - if (!isLargeClock) { - axes = - axes.map { axis -> - if (axis.key == GSFAxes.WIDTH.tag && axis.value > SMALL_CLOCK_MAX_WDTH) { - axis.copy(value = SMALL_CLOCK_MAX_WDTH) - } else { - axis - } - } + override fun onFontAxesChanged(settings: ClockAxisStyle) { + var axes = ClockAxisStyle(settings) + if (!isLargeClock && axes[GSFAxes.WIDTH] > SMALL_CLOCK_MAX_WDTH) { + axes[GSFAxes.WIDTH] = SMALL_CLOCK_MAX_WDTH } layerController.events.onFontAxesChanged(axes) diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt index 212b1e29d1b8..722d76beedbb 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt @@ -18,26 +18,36 @@ package com.android.systemui.shared.clocks import com.android.systemui.animation.AxisDefinition import com.android.systemui.plugins.clocks.AxisType +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockFontAxis -import com.android.systemui.plugins.clocks.ClockFontAxisSetting -fun AxisDefinition.toClockAxis( - type: AxisType, - currentValue: Float? = null, - name: String, - description: String, -): ClockFontAxis { - return ClockFontAxis( - key = this.tag, - type = type, - maxValue = this.maxValue, - minValue = this.minValue, - currentValue = currentValue ?: this.defaultValue, - name = name, - description = description, - ) -} +object FontUtils { + fun AxisDefinition.toClockAxis( + type: AxisType, + currentValue: Float? = null, + name: String, + description: String, + ): ClockFontAxis { + return ClockFontAxis( + key = this.tag, + type = type, + maxValue = this.maxValue, + minValue = this.minValue, + currentValue = currentValue ?: this.defaultValue, + name = name, + description = description, + ) + } + + fun ClockAxisStyle.put(def: AxisDefinition, value: Float? = null) { + this.put(def.tag, value ?: def.defaultValue) + } + + operator fun ClockAxisStyle.set(def: AxisDefinition, value: Float) { + this[def.tag] = value + } -fun AxisDefinition.toClockAxisSetting(value: Float? = null): ClockFontAxisSetting { - return ClockFontAxisSetting(this.tag, value ?: this.defaultValue) + operator fun ClockAxisStyle.get(def: AxisDefinition): Float { + return this[def.tag] ?: def.defaultValue + } } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt index 1d963af3ad22..7be9a936cbd3 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt @@ -26,10 +26,10 @@ import com.android.systemui.customization.R import com.android.systemui.log.core.Logger import com.android.systemui.plugins.clocks.AlarmData import com.android.systemui.plugins.clocks.ClockAnimations +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockEvents import com.android.systemui.plugins.clocks.ClockFaceConfig import com.android.systemui.plugins.clocks.ClockFaceEvents -import com.android.systemui.plugins.clocks.ClockFontAxisSetting import com.android.systemui.plugins.clocks.ThemeConfig import com.android.systemui.plugins.clocks.WeatherData import com.android.systemui.plugins.clocks.ZenData @@ -172,7 +172,7 @@ open class SimpleDigitalHandLayerController( override fun onZenDataChanged(data: ZenData) {} - override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) { + override fun onFontAxesChanged(axes: ClockAxisStyle) { view.updateAxes(axes) } } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt index ba32ab083063..4531aed0e83d 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt @@ -26,7 +26,7 @@ import androidx.annotation.VisibleForTesting import androidx.core.view.children import com.android.app.animation.Interpolators import com.android.systemui.customization.R -import com.android.systemui.plugins.clocks.ClockFontAxisSetting +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockLogger import com.android.systemui.plugins.clocks.VPoint import com.android.systemui.plugins.clocks.VPointF @@ -272,7 +272,7 @@ class FlexClockView(clockCtx: ClockContext) : ViewGroup(clockCtx.context) { invalidate() } - fun updateAxes(axes: List<ClockFontAxisSetting>) { + fun updateAxes(axes: ClockAxisStyle) { childViews.forEach { view -> view.updateAxes(axes) } requestLayout() } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt index da9e26ae3812..377a24c2899b 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt @@ -36,13 +36,12 @@ import android.view.animation.PathInterpolator import android.widget.TextView import com.android.app.animation.Interpolators import com.android.internal.annotations.VisibleForTesting +import com.android.systemui.animation.AxisDefinition import com.android.systemui.animation.GSFAxes import com.android.systemui.animation.TextAnimator import com.android.systemui.animation.TextAnimatorListener import com.android.systemui.customization.R -import com.android.systemui.plugins.clocks.ClockFontAxisSetting -import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.replace -import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.toFVar +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockLogger import com.android.systemui.plugins.clocks.VPoint import com.android.systemui.plugins.clocks.VPointF @@ -56,9 +55,9 @@ import com.android.systemui.shared.clocks.DigitTranslateAnimator import com.android.systemui.shared.clocks.DimensionParser import com.android.systemui.shared.clocks.FLEX_CLOCK_ID import com.android.systemui.shared.clocks.FontTextStyle +import com.android.systemui.shared.clocks.FontUtils.set import com.android.systemui.shared.clocks.ViewUtils.measuredSize import com.android.systemui.shared.clocks.ViewUtils.size -import com.android.systemui.shared.clocks.toClockAxisSetting import java.lang.Thread import kotlin.math.max import kotlin.math.min @@ -123,9 +122,9 @@ open class SimpleDigitalClockTextView( private val isLegacyFlex = clockCtx.settings.clockId == FLEX_CLOCK_ID private val fixedAodAxes = when { - !isLegacyFlex -> listOf(AOD_WEIGHT_AXIS, WIDTH_AXIS) - isLargeClock -> listOf(FLEX_AOD_LARGE_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS) - else -> listOf(FLEX_AOD_SMALL_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS) + !isLegacyFlex -> fromAxes(AOD_WEIGHT_AXIS, WIDTH_AXIS) + isLargeClock -> fromAxes(FLEX_AOD_LARGE_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS) + else -> fromAxes(FLEX_AOD_SMALL_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS) } private var lsFontVariation: String @@ -135,11 +134,11 @@ open class SimpleDigitalClockTextView( init { val roundAxis = if (!isLegacyFlex) ROUND_AXIS else FLEX_ROUND_AXIS val lsFontAxes = - if (!isLegacyFlex) listOf(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS) - else listOf(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS) + if (!isLegacyFlex) fromAxes(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS) + else fromAxes(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS) lsFontVariation = lsFontAxes.toFVar() - aodFontVariation = (fixedAodAxes + listOf(roundAxis, SLANT_AXIS)).toFVar() + aodFontVariation = fixedAodAxes.copyWith(fromAxes(roundAxis, SLANT_AXIS)).toFVar() fidgetFontVariation = buildFidgetVariation(lsFontAxes).toFVar() } @@ -201,9 +200,9 @@ open class SimpleDigitalClockTextView( invalidate() } - fun updateAxes(lsAxes: List<ClockFontAxisSetting>) { + fun updateAxes(lsAxes: ClockAxisStyle) { lsFontVariation = lsAxes.toFVar() - aodFontVariation = lsAxes.replace(fixedAodAxes).toFVar() + aodFontVariation = lsAxes.copyWith(fixedAodAxes).toFVar() fidgetFontVariation = buildFidgetVariation(lsAxes).toFVar() logger.updateAxes(lsFontVariation, aodFontVariation) @@ -220,19 +219,16 @@ open class SimpleDigitalClockTextView( invalidate() } - fun buildFidgetVariation(axes: List<ClockFontAxisSetting>): List<ClockFontAxisSetting> { - val result = mutableListOf<ClockFontAxisSetting>() - for (axis in axes) { - result.add( - FIDGET_DISTS.get(axis.key)?.let { (dist, midpoint) -> - ClockFontAxisSetting( - axis.key, - axis.value + dist * if (axis.value > midpoint) -1 else 1, - ) - } ?: axis - ) - } - return result + fun buildFidgetVariation(axes: ClockAxisStyle): ClockAxisStyle { + return ClockAxisStyle( + axes.items + .map { (key, value) -> + FIDGET_DISTS.get(key)?.let { (dist, midpoint) -> + key to value + dist * if (value > midpoint) -1 else 1 + } ?: (key to value) + } + .toMap() + ) } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { @@ -666,18 +662,22 @@ open class SimpleDigitalClockTextView( ) val AOD_COLOR = Color.WHITE - val LS_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(400f) - val AOD_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(200f) - val WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(85f) - val ROUND_AXIS = GSFAxes.ROUND.toClockAxisSetting(0f) - val SLANT_AXIS = GSFAxes.SLANT.toClockAxisSetting(0f) + private val LS_WEIGHT_AXIS = GSFAxes.WEIGHT to 400f + private val AOD_WEIGHT_AXIS = GSFAxes.WEIGHT to 200f + private val WIDTH_AXIS = GSFAxes.WIDTH to 85f + private val ROUND_AXIS = GSFAxes.ROUND to 0f + private val SLANT_AXIS = GSFAxes.SLANT to 0f // Axes for Legacy version of the Flex Clock - val FLEX_LS_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(600f) - val FLEX_AOD_LARGE_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(74f) - val FLEX_AOD_SMALL_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(133f) - val FLEX_LS_WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(100f) - val FLEX_AOD_WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(43f) - val FLEX_ROUND_AXIS = GSFAxes.ROUND.toClockAxisSetting(100f) + private val FLEX_LS_WEIGHT_AXIS = GSFAxes.WEIGHT to 600f + private val FLEX_AOD_LARGE_WEIGHT_AXIS = GSFAxes.WEIGHT to 74f + private val FLEX_AOD_SMALL_WEIGHT_AXIS = GSFAxes.WEIGHT to 133f + private val FLEX_LS_WIDTH_AXIS = GSFAxes.WIDTH to 100f + private val FLEX_AOD_WIDTH_AXIS = GSFAxes.WIDTH to 43f + private val FLEX_ROUND_AXIS = GSFAxes.ROUND to 100f + + private fun fromAxes(vararg axes: Pair<AxisDefinition, Float>): ClockAxisStyle { + return ClockAxisStyle(axes.map { (def, value) -> def.tag to value }.toMap()) + } } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt index 14d34d79512f..162218d8f071 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt @@ -87,7 +87,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { contentResolver, selectedUserInteractor, lazyKeyguardUpdateMonitor, - dumpManager + dumpManager, ) } @@ -116,9 +116,9 @@ class ActiveUnlockConfigTest : SysuiTestCase() { ) ) assertFalse( - activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( - ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY - ) + activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( + ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY + ) ) assertTrue( activeUnlockConfig.shouldAllowActiveUnlockFromOrigin( @@ -212,7 +212,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { secureSettings.putStringForUser( ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, "", - currentUser + currentUser, ) updateSetting( secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED) @@ -285,7 +285,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, "${BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED}" + "|${BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED}", - currentUser + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO)) @@ -328,7 +328,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { secureSettings.putStringForUser( ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, "${ActiveUnlockConfig.BiometricType.NONE.intValue}", - currentUser + currentUser, ) updateSetting( secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED) @@ -358,7 +358,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, "${ActiveUnlockConfig.BiometricType.ANY_FACE.intValue}" + "|${ActiveUnlockConfig.BiometricType.ANY_FINGERPRINT.intValue}", - currentUser + currentUser, ) updateSetting( secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED) @@ -397,10 +397,10 @@ class ActiveUnlockConfigTest : SysuiTestCase() { @Test fun isWakeupConsideredUnlockIntent_singleValue() { // GIVEN lift is considered an unlock intent - secureSettings.putIntForUser( + secureSettings.putStringForUser( ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, - PowerManager.WAKE_REASON_LIFT, - currentUser + PowerManager.WAKE_REASON_LIFT.toString(), + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) @@ -422,7 +422,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { PowerManager.WAKE_REASON_LIFT.toString() + "|" + PowerManager.WAKE_REASON_TAP.toString(), - currentUser + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) @@ -452,7 +452,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { secureSettings.putStringForUser( ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS, " ", - currentUser + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)) @@ -479,7 +479,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { secureSettings.putStringForUser( ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, PowerManager.WAKE_REASON_LIFT.toString(), - currentUser + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD)) @@ -501,7 +501,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { secureSettings.putStringForUser( ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD, " ", - currentUser + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD)) @@ -521,7 +521,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { PowerManager.WAKE_REASON_LIFT.toString() + "|" + PowerManager.WAKE_REASON_TAP.toString(), - currentUser + currentUser, ) updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD)) @@ -544,7 +544,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { secureSettings.putStringForUser( ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED, "-1", - currentUser + currentUser, ) // WHEN the setting updates @@ -581,7 +581,7 @@ class ActiveUnlockConfigTest : SysuiTestCase() { eq(uri), eq(false), capture(settingsObserverCaptor), - eq(UserHandle.USER_ALL) + eq(UserHandle.USER_ALL), ) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt index 245388c214a5..b0db8b70d296 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt @@ -22,12 +22,12 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.customization.R as customR import com.android.systemui.keyguard.ui.view.KeyguardRootView -import com.android.systemui.kosmos.Kosmos import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.res.R import com.android.systemui.shade.NotificationShadeWindowView import com.android.systemui.statusbar.StatusBarState.KEYGUARD import com.android.systemui.statusbar.StatusBarState.SHADE +import com.android.systemui.testKosmos import com.android.systemui.unfold.FakeUnfoldTransitionProvider import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider @@ -47,16 +47,14 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class KeyguardUnfoldTransitionTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val progressProvider: FakeUnfoldTransitionProvider = kosmos.fakeUnfoldTransitionProgressProvider - @Mock - private lateinit var keyguardRootView: KeyguardRootView + @Mock private lateinit var keyguardRootView: KeyguardRootView - @Mock - private lateinit var notificationShadeWindowView: NotificationShadeWindowView + @Mock private lateinit var notificationShadeWindowView: NotificationShadeWindowView @Mock private lateinit var statusBarStateController: StatusBarStateController @@ -71,10 +69,14 @@ class KeyguardUnfoldTransitionTest : SysuiTestCase() { xTranslationMax = context.resources.getDimensionPixelSize(R.dimen.keyguard_unfold_translation_x).toFloat() - underTest = KeyguardUnfoldTransition( - context, keyguardRootView, notificationShadeWindowView, - statusBarStateController, progressProvider - ) + underTest = + KeyguardUnfoldTransition( + context, + keyguardRootView, + notificationShadeWindowView, + statusBarStateController, + progressProvider, + ) underTest.setup() underTest.statusViewCentered = false @@ -88,9 +90,8 @@ class KeyguardUnfoldTransitionTest : SysuiTestCase() { underTest.statusViewCentered = true val view = View(context) - whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large)).thenReturn( - view - ) + whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large)) + .thenReturn(view) progressListener.onTransitionStarted() assertThat(view.translationX).isZero() @@ -110,9 +111,8 @@ class KeyguardUnfoldTransitionTest : SysuiTestCase() { whenever(statusBarStateController.getState()).thenReturn(SHADE) val view = View(context) - whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large)).thenReturn( - view - ) + whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large)) + .thenReturn(view) progressListener.onTransitionStarted() assertThat(view.translationX).isZero() @@ -133,9 +133,11 @@ class KeyguardUnfoldTransitionTest : SysuiTestCase() { val view = View(context) whenever( - notificationShadeWindowView - .findViewById<View>(customR.id.lockscreen_clock_view_large) - ).thenReturn(view) + notificationShadeWindowView.findViewById<View>( + customR.id.lockscreen_clock_view_large + ) + ) + .thenReturn(view) progressListener.onTransitionStarted() assertThat(view.translationX).isZero() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt index cde42bd00ba5..76606230a124 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt @@ -23,7 +23,6 @@ import androidx.test.filters.SmallTest import com.android.internal.accessibility.AccessibilityShortcutController import com.android.internal.accessibility.common.ShortcutConstants import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope @@ -31,6 +30,7 @@ import com.android.systemui.model.SysUiState import com.android.systemui.res.R import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.testKosmos import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -58,7 +58,7 @@ class ExtraDimDialogDelegateTest : SysuiTestCase() { private lateinit var extraDimDialogDelegate: ExtraDimDialogDelegate - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val testScope = kosmos.testScope @Mock private lateinit var dialog: SystemUIDialog @@ -79,7 +79,7 @@ class ExtraDimDialogDelegateTest : SysuiTestCase() { kosmos.testDispatcher, dialogFactory, accessibilityManager, - userTracker + userTracker, ) } @@ -94,7 +94,7 @@ class ExtraDimDialogDelegateTest : SysuiTestCase() { verify(dialog) .setPositiveButton( eq(R.string.accessibility_deprecate_extra_dim_dialog_button), - clickListener.capture() + clickListener.capture(), ) clickListener.firstValue.onClick(dialog, 0) @@ -110,7 +110,7 @@ class ExtraDimDialogDelegateTest : SysuiTestCase() { .flattenToString() ) ), - anyInt() + anyInt(), ) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt index 2713bb0f3e23..3040c12279ee 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt @@ -83,10 +83,11 @@ class FontScalingDialogDelegateTest : SysuiTestCase() { MockitoAnnotations.initMocks(this) testableLooper = TestableLooper.get(this) val mainHandler = Handler(testableLooper.looper) - systemSettings = FakeSettings() + val fakeSettings = FakeSettings() + systemSettings = fakeSettings // Guarantee that the systemSettings always starts with the default font scale. systemSettings.putFloatForUser(Settings.System.FONT_SCALE, 1.0f, userTracker.userId) - secureSettings = FakeSettings() + secureSettings = fakeSettings systemClock = FakeSystemClock() backgroundDelayableExecutor = FakeExecutor(systemClock) whenever(sysuiState.setFlag(anyLong(), anyBoolean())).thenReturn(sysuiState) @@ -207,9 +208,9 @@ class FontScalingDialogDelegateTest : SysuiTestCase() { dialog.show() val iconStartFrame: ViewGroup = dialog.findViewById(R.id.icon_start_frame)!! - secureSettings.putIntForUser( + secureSettings.putStringForUser( Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, - OFF, + OFF.toString(), userTracker.userId, ) @@ -220,12 +221,11 @@ class FontScalingDialogDelegateTest : SysuiTestCase() { backgroundDelayableExecutor.runAllReady() val currentSettings = - secureSettings.getIntForUser( + secureSettings.getStringForUser( Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, - /* def = */ OFF, userTracker.userId, ) - assertThat(currentSettings).isEqualTo(ON) + assertThat(currentSettings).isEqualTo(ON.toString()) dialog.dismiss() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java index 7e4704a6179a..d118ace08b85 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java @@ -141,6 +141,10 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { @Mock private QSSettingsPackageRepository mQSSettingsPackageRepository; @Mock + private HearingDevicesInputRoutingController.Factory mInputRoutingFactory; + @Mock + private HearingDevicesInputRoutingController mInputRoutingController; + @Mock private CachedBluetoothDevice mCachedDevice; @Mock private BluetoothDevice mDevice; @@ -184,6 +188,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { when(mCachedDevice.getBondState()).thenReturn(BOND_BONDED); when(mCachedDevice.getDeviceSide()).thenReturn(SIDE_LEFT); when(mHearingDeviceItem.getCachedBluetoothDevice()).thenReturn(mCachedDevice); + when(mInputRoutingFactory.create(any())).thenReturn(mInputRoutingController); mContext.setMockPackageManager(mPackageManager); } @@ -349,6 +354,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { setUpDeviceDialogWithoutPairNewDeviceButton(); mDialog.show(); + mExecutor.runAllReady(); ViewGroup ambientLayout = getAmbientLayout(mDialog); assertThat(ambientLayout.getVisibility()).isEqualTo(View.VISIBLE); @@ -401,7 +407,8 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { mExecutor, mAudioManager, mUiEventLogger, - mQSSettingsPackageRepository + mQSSettingsPackageRepository, + mInputRoutingFactory ); mDialog = mDialogDelegate.createDialog(); } @@ -438,7 +445,6 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { return dialog.requireViewById(R.id.ambient_layout); } - private int countChildWithoutSpace(ViewGroup viewGroup) { int spaceCount = 0; for (int i = 0; i < viewGroup.getChildCount(); i++) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingControllerTest.kt new file mode 100644 index 000000000000..0a41b771a335 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingControllerTest.kt @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2025 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.accessibility.hearingaid + +import android.media.AudioDeviceInfo +import android.media.AudioManager +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.HapClientProfile +import com.android.systemui.SysuiTestCase +import com.android.systemui.accessibility.hearingaid.HearingDevicesInputRoutingController.InputRoutingControlAvailableCallback +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.stub +import org.mockito.kotlin.verify + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +class HearingDevicesInputRoutingControllerTest : SysuiTestCase() { + + private val kosmos = Kosmos() + private val testScope = kosmos.testScope + private var hapClientProfile: HapClientProfile = mock() + private var cachedDevice: CachedBluetoothDevice = mock() + private var memberCachedDevice: CachedBluetoothDevice = mock() + private var btDevice: android.bluetooth.BluetoothDevice = mock() + private var audioManager: AudioManager = mock() + private lateinit var underTest: HearingDevicesInputRoutingController + private val testDispatcher = kosmos.testDispatcher + + @Before + fun setUp() { + hapClientProfile.stub { on { isProfileReady } doReturn true } + cachedDevice.stub { + on { device } doReturn btDevice + on { profiles } doReturn listOf(hapClientProfile) + } + memberCachedDevice.stub { + on { device } doReturn btDevice + on { profiles } doReturn listOf(hapClientProfile) + } + + underTest = HearingDevicesInputRoutingController(mContext, audioManager, testDispatcher) + underTest.setDevice(cachedDevice) + } + + @Test + fun isInputRoutingControlAvailable_validInput_supportHapProfile_returnTrue() { + testScope.runTest { + val mockInfoAddress = arrayOf(mockTestAddressInfo(TEST_ADDRESS)) + cachedDevice.stub { + on { address } doReturn TEST_ADDRESS + on { profiles } doReturn listOf(hapClientProfile) + } + audioManager.stub { + on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn mockInfoAddress + } + + var result: Boolean? = null + underTest.isInputRoutingControlAvailable( + object : InputRoutingControlAvailableCallback { + override fun onResult(available: Boolean) { + result = available + } + } + ) + + runCurrent() + assertThat(result).isTrue() + } + } + + @Test + fun isInputRoutingControlAvailable_notSupportHapProfile_returnFalse() { + testScope.runTest { + val mockInfoAddress = arrayOf(mockTestAddressInfo(TEST_ADDRESS)) + cachedDevice.stub { + on { address } doReturn TEST_ADDRESS + on { profiles } doReturn emptyList() + } + audioManager.stub { + on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn mockInfoAddress + } + + var result: Boolean? = null + underTest.isInputRoutingControlAvailable( + object : InputRoutingControlAvailableCallback { + override fun onResult(available: Boolean) { + result = available + } + } + ) + + runCurrent() + assertThat(result).isFalse() + } + } + + @Test + fun isInputRoutingControlAvailable_validInputMember_supportHapProfile_returnTrue() { + testScope.runTest { + val mockInfoAddress2 = arrayOf(mockTestAddressInfo(TEST_ADDRESS_2)) + cachedDevice.stub { + on { address } doReturn TEST_ADDRESS + on { profiles } doReturn listOf(hapClientProfile) + on { memberDevice } doReturn (setOf(memberCachedDevice)) + } + memberCachedDevice.stub { on { address } doReturn TEST_ADDRESS_2 } + audioManager.stub { + on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn mockInfoAddress2 + } + + var result: Boolean? = null + underTest.isInputRoutingControlAvailable( + object : InputRoutingControlAvailableCallback { + override fun onResult(available: Boolean) { + result = available + } + } + ) + + runCurrent() + assertThat(result).isTrue() + } + } + + @Test + fun isAvailable_notValidInputDevice_returnFalse() { + testScope.runTest { + cachedDevice.stub { + on { address } doReturn TEST_ADDRESS + on { profiles } doReturn listOf(hapClientProfile) + } + audioManager.stub { + on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn emptyArray() + } + + var result: Boolean? = null + underTest.isInputRoutingControlAvailable( + object : InputRoutingControlAvailableCallback { + override fun onResult(available: Boolean) { + result = available + } + } + ) + + runCurrent() + assertThat(result).isFalse() + } + } + + @Test + fun selectInputRouting_builtinMic_setMicrophonePreferredForCallsFalse() { + underTest.selectInputRouting( + HearingDevicesInputRoutingController.InputRoutingValue.BUILTIN_MIC.ordinal + ) + + verify(btDevice).isMicrophonePreferredForCalls = false + } + + private fun mockTestAddressInfo(address: String): AudioDeviceInfo { + val info: AudioDeviceInfo = mock() + info.stub { + on { type } doReturn AudioDeviceInfo.TYPE_BLE_HEADSET + on { this.address } doReturn address + } + + return info + } + + companion object { + private const val TEST_ADDRESS = "55:66:77:88:99:AA" + private const val TEST_ADDRESS_2 = "55:66:77:88:99:BB" + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt index 8c5fad3906ed..85733124aedb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt @@ -32,7 +32,6 @@ import com.android.internal.statusbar.IStatusBarService import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest @@ -50,6 +49,7 @@ import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.headsup.HeadsUpManager import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager +import com.android.systemui.testKosmos import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor @@ -74,7 +74,7 @@ import org.mockito.junit.MockitoJUnit @SmallTest @RunWith(AndroidJUnit4::class) class BackActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val executor = FakeExecutor(FakeSystemClock()) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt index 648d74d20cc5..29a0b6922b2f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt @@ -22,8 +22,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent @@ -34,7 +34,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class CameraAutoRotateRepositoryImplTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val settings = kosmos.fakeSettings private val testUser = UserHandle.of(1) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt index b73a212c9bd1..2e357d8a8652 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt @@ -22,8 +22,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent @@ -38,7 +38,7 @@ import org.mockito.Mockito @RunWith(AndroidJUnit4::class) @android.platform.test.annotations.EnabledOnRavenwood class CameraSensorPrivacyRepositoryImplTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val testUser = UserHandle.of(1) private val privacyManager = mock<SensorPrivacyManager>() @@ -46,7 +46,7 @@ class CameraSensorPrivacyRepositoryImplTest : SysuiTestCase() { CameraSensorPrivacyRepositoryImpl( testScope.testScheduler, testScope.backgroundScope, - privacyManager + privacyManager, ) @Test @@ -87,7 +87,7 @@ class CameraSensorPrivacyRepositoryImplTest : SysuiTestCase() { .addSensorPrivacyListener( ArgumentMatchers.eq(SensorPrivacyManager.Sensors.CAMERA), ArgumentMatchers.eq(testUser.identifier), - captor.capture() + captor.capture(), ) val sensorPrivacyCallback = captor.value!! diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt index 6c8097ed7166..b3d898396497 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt @@ -21,7 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -32,7 +32,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) @android.platform.test.annotations.EnabledOnRavenwood class FakeCameraAutoRotateRepositoryTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val underTest = kosmos.fakeCameraAutoRotateRepository private val testUser = UserHandle.of(1) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt index 7161c2c13a60..6b9a7de2e781 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt @@ -21,7 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -32,7 +32,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) @android.platform.test.annotations.EnabledOnRavenwood class FakeCameraSensorPrivacyRepositoryTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val underTest = kosmos.fakeCameraSensorPrivacyRepository private val testUser = UserHandle.of(1) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt index 0c97750ba281..6710575e32d2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.keyguardUpdateMonitor import com.android.systemui.SysuiTestCase +import com.android.systemui.condition.testStart import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE @@ -55,6 +56,7 @@ class DeviceInactiveConditionTest : SysuiTestCase() { Kosmos.Fixture { DeviceInactiveCondition( applicationCoroutineScope, + applicationCoroutineScope, keyguardStateController, wakefulnessLifecycle, keyguardUpdateMonitor, @@ -67,7 +69,7 @@ class DeviceInactiveConditionTest : SysuiTestCase() { fun asleep_conditionTrue() = kosmos.runTest { // Condition is false to start. - underTest.start() + testStart(underTest) assertThat(underTest.isConditionMet).isFalse() // Condition is true when device goes to sleep. @@ -79,7 +81,7 @@ class DeviceInactiveConditionTest : SysuiTestCase() { fun dozingAndAsleep_conditionFalse() = kosmos.runTest { // Condition is true when device is asleep. - underTest.start() + testStart(underTest) sleep() assertThat(underTest.isConditionMet).isTrue() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt index f4a1c90a5471..95334b5aaf09 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt @@ -55,9 +55,11 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { fun setUp() { runBlocking { kosmos.fakeUserRepository.asMainUser() } with(kosmos.fakeSettings) { - putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, false, MAIN_USER_ID) - putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, false, MAIN_USER_ID) - putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, false, MAIN_USER_ID) + putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_NEVER, + MAIN_USER_ID, + ) } } @@ -67,9 +69,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, - true, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_CHARGING, MAIN_USER_ID, ) @@ -91,9 +93,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - true, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_DOCKED, MAIN_USER_ID, ) @@ -118,9 +120,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, - true, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_CHARGING_UPRIGHT, MAIN_USER_ID, ) @@ -144,19 +146,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, - false, - MAIN_USER_ID, - ) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - false, - MAIN_USER_ID, - ) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, - false, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_NEVER, MAIN_USER_ID, ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt index 310bf6486413..d6f7145bd770 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt @@ -21,10 +21,12 @@ import android.app.admin.devicePolicyManager import android.content.Intent import android.content.pm.UserInfo import android.os.UserManager +import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest @@ -32,6 +34,7 @@ import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository +import com.android.systemui.util.settings.fakeSettings import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull @@ -82,6 +85,19 @@ class CommunalSettingsInteractorTest : SysuiTestCase() { assertEquals(USER_INFO_WORK.id, disallowedUser!!.id) } + @Test + fun whenToStartHub_matchesRepository() = + kosmos.runTest { + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_CHARGING, + MAIN_USER_INFO.id, + ) + + val startCondition by collectLastValue(underTest.whenToStartHub) + assertEquals(startCondition, WhenToStartHub.WHILE_CHARGING) + } + private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) { whenever( kosmos.devicePolicyManager.getKeyguardDisabledFeatures( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt index df10d058c5d1..b08e6761d92f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt @@ -16,12 +16,14 @@ package com.android.systemui.communal.widgets +import android.appwidget.AppWidgetProviderInfo import android.content.pm.UserInfo import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository +import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.communalSettingsInteractor import com.android.systemui.communal.domain.interactor.setCommunalEnabled @@ -49,6 +51,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.never +import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -65,6 +68,7 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { private lateinit var appWidgetIdToRemove: MutableSharedFlow<Int> + private lateinit var communalInteractorSpy: CommunalInteractor private lateinit var underTest: CommunalAppWidgetHostStartable @Before @@ -78,12 +82,13 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { helper = kosmos.fakeGlanceableHubMultiUserHelper appWidgetIdToRemove = MutableSharedFlow() whenever(appWidgetHost.appWidgetIdToRemove).thenReturn(appWidgetIdToRemove) + communalInteractorSpy = spy(kosmos.communalInteractor) underTest = CommunalAppWidgetHostStartable( { appWidgetHost }, { communalWidgetHost }, - { kosmos.communalInteractor }, + { communalInteractorSpy }, { kosmos.communalSettingsInteractor }, { kosmos.keyguardInteractor }, { kosmos.fakeUserTracker }, @@ -259,6 +264,41 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { } @Test + fun removeNotLockscreenWidgets_whenCommunalIsAvailable() = + with(kosmos) { + testScope.runTest { + // Communal is available + setCommunalAvailable(true) + kosmos.fakeUserTracker.set( + userInfos = listOf(MAIN_USER_INFO), + selectedUserIndex = 0, + ) + fakeCommunalWidgetRepository.addWidget( + appWidgetId = 1, + userId = MAIN_USER_INFO.id, + category = AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD, + ) + fakeCommunalWidgetRepository.addWidget(appWidgetId = 2, userId = MAIN_USER_INFO.id) + fakeCommunalWidgetRepository.addWidget( + appWidgetId = 3, + userId = MAIN_USER_INFO.id, + category = AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD, + ) + + underTest.start() + runCurrent() + + val communalWidgets by + collectLastValue(fakeCommunalWidgetRepository.communalWidgets) + assertThat(communalWidgets).hasSize(1) + assertThat(communalWidgets!![0].appWidgetId).isEqualTo(2) + + verify(communalInteractorSpy).deleteWidget(1) + verify(communalInteractorSpy).deleteWidget(3) + } + } + + @Test fun onStartHeadlessSystemUser_registerWidgetManager_whenCommunalIsAvailable() = with(kosmos) { testScope.runTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt index 6c7783ae44e1..28b9e733be94 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.display.data.repository import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl import com.android.systemui.SysuiTestCase import com.android.systemui.dump.dumpManager import com.android.systemui.kosmos.testScope diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java deleted file mode 100644 index ccadd143b582..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2023 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.dreams.conditions; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.assist.AssistManager; -import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener; -import com.android.systemui.shared.condition.Condition; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidJUnit4.class) -@android.platform.test.annotations.EnabledOnRavenwood -public class AssistantAttentionConditionTest extends SysuiTestCase { - @Mock - Condition.Callback mCallback; - @Mock - AssistManager mAssistManager; - @Mock - CoroutineScope mScope; - - private AssistantAttentionCondition mAssistantAttentionCondition; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - - mAssistantAttentionCondition = new AssistantAttentionCondition(mScope, mAssistManager); - // Adding a callback also starts the condition. - mAssistantAttentionCondition.addCallback(mCallback); - } - - @Test - public void testEnableVisualQueryDetection() { - verify(mAssistManager).addVisualQueryAttentionListener( - any(VisualQueryAttentionListener.class)); - } - - @Test - public void testDisableVisualQueryDetection() { - mAssistantAttentionCondition.stop(); - verify(mAssistManager).removeVisualQueryAttentionListener( - any(VisualQueryAttentionListener.class)); - } - - @Test - public void testAttentionChangedTriggersCondition() { - final ArgumentCaptor<VisualQueryAttentionListener> argumentCaptor = - ArgumentCaptor.forClass(VisualQueryAttentionListener.class); - verify(mAssistManager).addVisualQueryAttentionListener(argumentCaptor.capture()); - - argumentCaptor.getValue().onAttentionGained(); - assertThat(mAssistantAttentionCondition.isConditionMet()).isTrue(); - - argumentCaptor.getValue().onAttentionLost(); - assertThat(mAssistantAttentionCondition.isConditionMet()).isFalse(); - - verify(mCallback, times(2)).onConditionChanged(eq(mAssistantAttentionCondition)); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.kt new file mode 100644 index 000000000000..eefc61a035c3 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.kt @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2025 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.dreams.conditions + +import android.platform.test.annotations.EnabledOnRavenwood +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.assist.AssistManager +import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.shared.condition.Condition +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq + +@SmallTest +@RunWith(AndroidJUnit4::class) +@EnabledOnRavenwood +class AssistantAttentionConditionTest : SysuiTestCase() { + private val kosmos = Kosmos() + + @Mock private lateinit var callback: Condition.Callback + + @Mock private lateinit var assistManager: AssistManager + + private lateinit var underTest: AssistantAttentionCondition + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + underTest = AssistantAttentionCondition(kosmos.testScope, assistManager) + // Adding a callback also starts the condition. + underTest.addCallback(callback) + } + + @Test + fun testEnableVisualQueryDetection() = + kosmos.runTest { Mockito.verify(assistManager).addVisualQueryAttentionListener(any()) } + + @Test + fun testDisableVisualQueryDetection() = + kosmos.runTest { + underTest.stop() + Mockito.verify(assistManager).removeVisualQueryAttentionListener(any()) + } + + @Test + fun testAttentionChangedTriggersCondition() = + kosmos.runTest { + val argumentCaptor = argumentCaptor<VisualQueryAttentionListener>() + Mockito.verify(assistManager).addVisualQueryAttentionListener(argumentCaptor.capture()) + + argumentCaptor.lastValue.onAttentionGained() + Truth.assertThat(underTest.isConditionMet).isTrue() + + argumentCaptor.lastValue.onAttentionLost() + Truth.assertThat(underTest.isConditionMet).isFalse() + + Mockito.verify(callback, Mockito.times(2)).onConditionChanged(eq(underTest)) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java deleted file mode 100644 index 58c17e2a7286..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2023 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.dreams.conditions; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.DreamManager; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.shared.condition.Condition; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidJUnit4.class) -@android.platform.test.annotations.EnabledOnRavenwood -public class DreamConditionTest extends SysuiTestCase { - @Mock - Condition.Callback mCallback; - - @Mock - DreamManager mDreamManager; - - @Mock - KeyguardUpdateMonitor mKeyguardUpdateMonitor; - - @Mock - CoroutineScope mScope; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - } - - /** - * Ensure a dreaming state immediately triggers the condition. - */ - @Test - public void testInitialDreamingState() { - when(mDreamManager.isDreaming()).thenReturn(true); - final DreamCondition condition = new DreamCondition(mScope, mDreamManager, - mKeyguardUpdateMonitor); - condition.addCallback(mCallback); - - verify(mCallback).onConditionChanged(eq(condition)); - assertThat(condition.isConditionMet()).isTrue(); - } - - /** - * Ensure a non-dreaming state does not trigger the condition. - */ - @Test - public void testInitialNonDreamingState() { - when(mDreamManager.isDreaming()).thenReturn(false); - final DreamCondition condition = new DreamCondition(mScope, mDreamManager, - mKeyguardUpdateMonitor); - condition.addCallback(mCallback); - - verify(mCallback, never()).onConditionChanged(eq(condition)); - assertThat(condition.isConditionMet()).isFalse(); - } - - /** - * Ensure that changing dream state triggers condition. - */ - @Test - public void testChange() { - final ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCaptor = - ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); - when(mDreamManager.isDreaming()).thenReturn(true); - final DreamCondition condition = new DreamCondition(mScope, mDreamManager, - mKeyguardUpdateMonitor); - condition.addCallback(mCallback); - verify(mKeyguardUpdateMonitor).registerCallback(callbackCaptor.capture()); - - clearInvocations(mCallback); - callbackCaptor.getValue().onDreamingStateChanged(false); - verify(mCallback).onConditionChanged(eq(condition)); - assertThat(condition.isConditionMet()).isFalse(); - - clearInvocations(mCallback); - callbackCaptor.getValue().onDreamingStateChanged(true); - verify(mCallback).onConditionChanged(eq(condition)); - assertThat(condition.isConditionMet()).isTrue(); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.kt new file mode 100644 index 000000000000..302a6e1f432f --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2025 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.dreams.conditions + +import android.app.DreamManager +import android.platform.test.annotations.EnabledOnRavenwood +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.shared.condition.Condition +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +@EnabledOnRavenwood +class DreamConditionTest : SysuiTestCase() { + private val kosmos = Kosmos() + + @Mock private lateinit var callback: Condition.Callback + + @Mock private lateinit var dreamManager: DreamManager + + @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + } + + /** Ensure a dreaming state immediately triggers the condition. */ + @Test + fun testInitialDreamingState() = + kosmos.runTest { + whenever(dreamManager.isDreaming).thenReturn(true) + val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor) + condition.addCallback(callback) + runCurrent() + + Mockito.verify(callback).onConditionChanged(eq(condition)) + Truth.assertThat(condition.isConditionMet).isTrue() + } + + /** Ensure a non-dreaming state does not trigger the condition. */ + @Test + fun testInitialNonDreamingState() = + kosmos.runTest { + whenever(dreamManager.isDreaming).thenReturn(false) + val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor) + condition.addCallback(callback) + + Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(condition)) + Truth.assertThat(condition.isConditionMet).isFalse() + } + + /** Ensure that changing dream state triggers condition. */ + @Test + fun testChange() = + kosmos.runTest { + val callbackCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>() + whenever(dreamManager.isDreaming).thenReturn(true) + val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor) + condition.addCallback(callback) + runCurrent() + Mockito.verify(keyguardUpdateMonitor).registerCallback(callbackCaptor.capture()) + + Mockito.clearInvocations(callback) + callbackCaptor.lastValue.onDreamingStateChanged(false) + runCurrent() + Mockito.verify(callback).onConditionChanged(eq(condition)) + Truth.assertThat(condition.isConditionMet).isFalse() + + Mockito.clearInvocations(callback) + callbackCaptor.lastValue.onDreamingStateChanged(true) + runCurrent() + Mockito.verify(callback).onConditionChanged(eq(condition)) + Truth.assertThat(condition.isConditionMet).isTrue() + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt index f2a6c11b872e..722976131caf 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt @@ -26,9 +26,9 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.education.data.model.EduDeviceConnectionTime import com.android.systemui.education.data.model.GestureEduModel import com.android.systemui.education.domain.interactor.mockEduInputManager -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import java.io.File import javax.inject.Provider @@ -48,7 +48,7 @@ import org.junit.runner.RunWith class ContextualEducationRepositoryTest : SysuiTestCase() { private lateinit var underTest: UserContextualEducationRepository - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val dsScopeProvider: Provider<CoroutineScope> = Provider { TestScope(kosmos.testDispatcher).backgroundScope @@ -70,7 +70,7 @@ class ContextualEducationRepositoryTest : SysuiTestCase() { testContext, dsScopeProvider, kosmos.mockEduInputManager, - kosmos.testDispatcher + kosmos.testDispatcher, ) underTest.setUser(testUserId) } @@ -109,7 +109,7 @@ class ContextualEducationRepositoryTest : SysuiTestCase() { lastEducationTime = kosmos.fakeEduClock.instant(), usageSessionStartTime = kosmos.fakeEduClock.instant(), userId = testUserId, - gestureType = BACK + gestureType = BACK, ) underTest.updateGestureEduModel(BACK) { newModel } val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt index 5030d1e49da0..0f75e57ce771 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt @@ -21,9 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.haptics.msdl.msdlPlayer -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.VibratorHelper +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat @@ -45,7 +45,7 @@ import org.mockito.junit.MockitoRule @RunWith(AndroidJUnit4::class) class HapticSliderPluginTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() @Rule @JvmField val mMockitoRule: MockitoRule = MockitoJUnit.rule() @Mock private lateinit var vibratorHelper: VibratorHelper diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt index 798c5ab817a5..39b5e81345ee 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt @@ -23,9 +23,9 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.inputdevice.data.model.UserDeviceConnectionStatus import com.android.systemui.keyboard.data.repository.keyboardRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.touchpad.data.repository.touchpadRepository import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.user.data.repository.userRepository @@ -41,7 +41,7 @@ import org.junit.runner.RunWith class UserInputDeviceRepositoryTest : SysuiTestCase() { private lateinit var underTest: UserInputDeviceRepository - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val keyboardRepository = kosmos.keyboardRepository private val touchpadRepository = kosmos.touchpadRepository @@ -54,7 +54,7 @@ class UserInputDeviceRepositoryTest : SysuiTestCase() { kosmos.testDispatcher, keyboardRepository, touchpadRepository, - kosmos.userRepository + kosmos.userRepository, ) userRepository.setUserInfos(USER_INFOS) } @@ -72,7 +72,7 @@ class UserInputDeviceRepositoryTest : SysuiTestCase() { assertThat(isAnyKeyboardConnected) .containsExactly( UserDeviceConnectionStatus(isConnected = true, USER_INFOS[0].id), - UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id) + UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id), ) .inOrder() } @@ -90,16 +90,13 @@ class UserInputDeviceRepositoryTest : SysuiTestCase() { assertThat(isAnyTouchpadConnected) .containsExactly( UserDeviceConnectionStatus(isConnected = true, USER_INFOS[0].id), - UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id) + UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id), ) .inOrder() } companion object { private val USER_INFOS = - listOf( - UserInfo(100, "First User", 0), - UserInfo(101, "Second User", 0), - ) + listOf(UserInfo(100, "First User", 0), UserInfo(101, "Second User", 0)) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt index 274880b484cc..6bd0fb0e17a1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt @@ -23,9 +23,9 @@ import android.view.inputmethod.InputMethodSubtype import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock @@ -47,7 +47,7 @@ class InputMethodRepositoryTest : SysuiTestCase() { @Mock private lateinit var inputMethodManager: InputMethodManager - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private lateinit var underTest: InputMethodRepository @@ -72,7 +72,7 @@ class InputMethodRepositoryTest : SysuiTestCase() { inputMethodManager.getEnabledInputMethodSubtypeListAsUser( any(), anyBoolean(), - eq(USER_HANDLE) + eq(USER_HANDLE), ) ) .thenReturn(listOf()) @@ -97,7 +97,7 @@ class InputMethodRepositoryTest : SysuiTestCase() { inputMethodManager.getEnabledInputMethodSubtypeListAsUser( eq(selectedImiId), anyBoolean(), - eq(USER_HANDLE) + eq(USER_HANDLE), ) ) .thenReturn( @@ -125,7 +125,7 @@ class InputMethodRepositoryTest : SysuiTestCase() { verify(inputMethodManager) .showInputMethodPickerFromSystem( /* showAuxiliarySubtypes = */ eq(true), - /* displayId = */ eq(displayId) + /* displayId = */ eq(displayId), ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt index 8e6de2f04279..9e129a43b4cb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt @@ -22,8 +22,8 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.inputmethod.data.model.InputMethodModel import com.android.systemui.inputmethod.data.repository.fakeInputMethodRepository import com.android.systemui.inputmethod.data.repository.inputMethodRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import java.util.UUID import kotlinx.coroutines.test.runTest @@ -34,7 +34,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class InputMethodInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val fakeInputMethodRepository = kosmos.fakeInputMethodRepository @@ -148,7 +148,7 @@ class InputMethodInteractorTest : SysuiTestCase() { subtypes = List(auxiliarySubtypes + nonAuxiliarySubtypes) { InputMethodModel.Subtype(subtypeId = it, isAuxiliary = it < auxiliarySubtypes) - } + }, ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt index 1bb4805d4f16..655c646cd34c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt @@ -34,7 +34,6 @@ import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcut import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper import com.android.systemui.keyboard.shortcut.shortcutHelperViewModel -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testDispatcher @@ -43,6 +42,7 @@ import com.android.systemui.plugins.activityStarter import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.userTracker import com.android.systemui.statusbar.phone.systemUIDialogFactory +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -60,7 +60,7 @@ class ShortcutHelperDialogStarterTest : SysuiTestCase() { private val fakeMultiTaskingSource = FakeKeyboardShortcutGroupsSource() private val mockUserContext: Context = mock() private val kosmos = - Kosmos().also { + testKosmos().also { it.testCase = this it.testDispatcher = UnconfinedTestDispatcher() it.shortcutHelperSystemShortcutsSource = fakeSystemSource diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt index be9e93c64053..ba57ffd37053 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt @@ -26,7 +26,7 @@ import com.android.systemui.keyboard.stickykeys.StickyKeysLogger import com.android.systemui.keyboard.stickykeys.shared.model.Locked import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -52,19 +52,19 @@ class StickyKeysIndicatorCoordinatorTest : SysuiTestCase() { fun setup() { val dialogFactory = mock<StickyKeyDialogFactory>() whenever(dialogFactory.create(any())).thenReturn(dialog) - val keyboardRepository = Kosmos().keyboardRepository + val keyboardRepository = testKosmos().keyboardRepository val viewModel = StickyKeysIndicatorViewModel( stickyKeysRepository, keyboardRepository, - testScope.backgroundScope + testScope.backgroundScope, ) coordinator = StickyKeysIndicatorCoordinator( testScope.backgroundScope, dialogFactory, viewModel, - mock<StickyKeysLogger>() + mock<StickyKeysLogger>(), ) coordinator.startListening() keyboardRepository.setIsAnyKeyboardConnected(true) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt index 9daf0ffd34b4..642b2e3fb164 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt @@ -33,7 +33,6 @@ import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.ALT_GR import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.CTRL import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.META import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos @@ -64,7 +63,7 @@ class StickyKeysIndicatorViewModelTest : SysuiTestCase() { private val inputManager = mock<InputManager>() private val keyboardRepository = FakeKeyboardRepository() private val secureSettings = kosmos.fakeSettings - private val userRepository = Kosmos().fakeUserRepository + private val userRepository = testKosmos().fakeUserRepository private val captor = ArgumentCaptor.forClass(InputManager.StickyModifierStateListener::class.java) @@ -117,9 +116,9 @@ class StickyKeysIndicatorViewModelTest : SysuiTestCase() { } private fun setStickyKeySetting(enabled: Boolean) { - val newValue = if (enabled) "1" else "0" + val newValue = if (enabled) 1 else 0 val defaultUser = userRepository.getSelectedUserInfo().id - secureSettings.putStringForUser(ACCESSIBILITY_STICKY_KEYS, newValue, defaultUser) + secureSettings.putIntForUser(ACCESSIBILITY_STICKY_KEYS, newValue, defaultUser) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt index baf3b5b4430f..3f1cadc5fe76 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt @@ -23,12 +23,12 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.defaultDeviceState import com.android.systemui.deviceStateManager import com.android.systemui.flags.FeatureFlags -import com.android.systemui.kosmos.Kosmos import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argThat import java.util.function.Predicate @@ -68,7 +68,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController @Mock private lateinit var powerManager: PowerManager @Mock private lateinit var wallpaperManager: WallpaperManager - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val deviceStateManager = kosmos.deviceStateManager @Mock @@ -92,7 +92,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { surfaceControl1, Rect(), mock(ActivityManager.RunningTaskInfo::class.java), - false + false, ) private var surfaceControl2 = mock(SurfaceControl::class.java) @@ -113,7 +113,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { surfaceControl2, Rect(), mock(ActivityManager.RunningTaskInfo::class.java), - false + false, ) private lateinit var remoteAnimationTargets: Array<RemoteAnimationTarget> @@ -135,7 +135,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { surfaceControlWp, Rect(), mock(ActivityManager.RunningTaskInfo::class.java), - false + false, ) private lateinit var wallpaperTargets: Array<RemoteAnimationTarget> @@ -157,7 +157,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { surfaceControlLockWp, Rect(), mock(ActivityManager.RunningTaskInfo::class.java), - false + false, ) private lateinit var lockWallpaperTargets: Array<RemoteAnimationTarget> private var shouldPerformSmartspaceTransition = false @@ -179,14 +179,14 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { notificationShadeWindowController, powerManager, wallpaperManager, - deviceStateManager + deviceStateManager, ) { override fun shouldPerformSmartspaceTransition(): Boolean = shouldPerformSmartspaceTransition } keyguardUnlockAnimationController.setLauncherUnlockController( "", - launcherUnlockAnimationController + launcherUnlockAnimationController, ) whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) @@ -227,7 +227,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { arrayOf(), arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>() @@ -259,7 +259,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) // Since the animation is running, we should not have finished the remote animation. @@ -282,7 +282,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) verify(listener).onUnlockAnimationStarted(any(), eq(true), any(), any()) @@ -303,7 +303,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) verify(listener).onUnlockAnimationStarted(any(), eq(false), any(), any()) @@ -327,7 +327,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - true /* requestedShowSurfaceBehindKeyguard */ + true, /* requestedShowSurfaceBehindKeyguard */ ) assertTrue(keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.isRunning) @@ -351,7 +351,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - true /* requestedShowSurfaceBehindKeyguard */ + true, /* requestedShowSurfaceBehindKeyguard */ ) assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) @@ -373,7 +373,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) @@ -389,7 +389,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - true /* requestedShowSurfaceBehindKeyguard */ + true, /* requestedShowSurfaceBehindKeyguard */ ) assertFalse(keyguardUnlockAnimationController.canPerformInWindowLauncherAnimations()) @@ -406,7 +406,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) @@ -427,7 +427,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, lockWallpaperTargets, 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) for (i in 0..10) { @@ -471,7 +471,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) // Cancel the animator so we can verify only the setSurfaceBehind call below. @@ -492,7 +492,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>() verify( surfaceTransactionApplier, - times(1).description("WallpaperSurface was expected to receive scheduleApply once") + times(1).description("WallpaperSurface was expected to receive scheduleApply once"), ) .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp }) @@ -523,7 +523,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) // Cancel the animator so we can verify only the setSurfaceBehind call below. @@ -539,7 +539,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>() verify( surfaceTransactionApplier, - atLeastOnce().description("Wallpaper surface has not " + "received scheduleApply") + atLeastOnce().description("Wallpaper surface has not " + "received scheduleApply"), ) .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp }) @@ -562,7 +562,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { wallpaperTargets, arrayOf(), 0 /* startTime */, - false /* requestedShowSurfaceBehindKeyguard */ + false, /* requestedShowSurfaceBehindKeyguard */ ) // Stop the animator - we just want to test whether the override is not applied. @@ -578,7 +578,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>() verify( surfaceTransactionApplier, - atLeastOnce().description("Wallpaper surface has not " + "received scheduleApply") + atLeastOnce().description("Wallpaper surface has not " + "received scheduleApply"), ) .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp }) @@ -588,7 +588,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { assertEquals( "Wallpaper surface was expected to have opacity 1", 1f, - captorWp.getLastValue().alpha + captorWp.getLastValue().alpha, ) verifyNoMoreInteractions(surfaceTransactionApplier) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt index 6bc8000b0519..04f7fe1a6487 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt @@ -21,10 +21,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.policy.CastDevice import com.android.systemui.statusbar.policy.fakeCastController +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runCurrent @@ -34,7 +34,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class MediaRouterRepositoryTest : SysuiTestCase() { - val kosmos = Kosmos() + val kosmos = testKosmos() val testScope = kosmos.testScope val castController = kosmos.fakeCastController diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java deleted file mode 100644 index 5250d56edc0b..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2023 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.process.condition; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.testing.TestableLooper; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.process.ProcessWrapper; -import com.android.systemui.shared.condition.Condition; -import com.android.systemui.shared.condition.Monitor; -import com.android.systemui.util.concurrency.FakeExecutor; -import com.android.systemui.util.time.FakeSystemClock; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@TestableLooper.RunWithLooper -@SmallTest -public class SystemProcessConditionTest extends SysuiTestCase { - @Mock - ProcessWrapper mProcessWrapper; - - @Mock - Monitor.Callback mCallback; - - @Mock - CoroutineScope mScope; - - private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - } - - /** - * Verifies condition reports false when tracker reports the process is being ran by the - * system user. - */ - @Test - public void testConditionFailsWithNonSystemProcess() { - - final Condition condition = new SystemProcessCondition(mScope, mProcessWrapper); - when(mProcessWrapper.isSystemUser()).thenReturn(false); - - final Monitor monitor = new Monitor(mExecutor); - - monitor.addSubscription(new Monitor.Subscription.Builder(mCallback) - .addCondition(condition) - .build()); - - mExecutor.runAllReady(); - - verify(mCallback).onConditionsChanged(false); - } - - /** - * Verifies condition reports true when tracker reports the process is being ran by the - * system user. - */ - @Test - public void testConditionSucceedsWithSystemProcess() { - - final Condition condition = new SystemProcessCondition(mScope, mProcessWrapper); - when(mProcessWrapper.isSystemUser()).thenReturn(true); - - final Monitor monitor = new Monitor(mExecutor); - - monitor.addSubscription(new Monitor.Subscription.Builder(mCallback) - .addCondition(condition) - .build()); - - mExecutor.runAllReady(); - - verify(mCallback).onConditionsChanged(true); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.kt new file mode 100644 index 000000000000..21524d97d7af --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.kt @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2025 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.process.condition + +import android.testing.TestableLooper.RunWithLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.process.ProcessWrapper +import com.android.systemui.shared.condition.Condition +import com.android.systemui.shared.condition.Monitor +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.whenever + +@RunWith(AndroidJUnit4::class) +@RunWithLooper +@SmallTest +class SystemProcessConditionTest : SysuiTestCase() { + private val kosmos = Kosmos() + + @Mock private lateinit var processWrapper: ProcessWrapper + + @Mock private lateinit var callback: Monitor.Callback + + private val executor = FakeExecutor(FakeSystemClock()) + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + } + + /** + * Verifies condition reports false when tracker reports the process is being ran by the system + * user. + */ + @Test + fun testConditionFailsWithNonSystemProcess() = + kosmos.runTest { + val condition: Condition = SystemProcessCondition(kosmos.testScope, processWrapper) + whenever(processWrapper.isSystemUser).thenReturn(false) + + val monitor = Monitor(executor) + + monitor.addSubscription( + Monitor.Subscription.Builder(callback).addCondition(condition).build() + ) + + executor.runAllReady() + runCurrent() + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(false) + } + + /** + * Verifies condition reports true when tracker reports the process is being ran by the system + * user. + */ + @Test + fun testConditionSucceedsWithSystemProcess() = + kosmos.runTest { + val condition: Condition = SystemProcessCondition(testScope, processWrapper) + whenever(processWrapper.isSystemUser).thenReturn(true) + + val monitor = Monitor(executor) + + monitor.addSubscription( + Monitor.Subscription.Builder(callback).addCondition(condition).build() + ) + + executor.runAllReady() + runCurrent() + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(true) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java index 0f631509bfba..d9990ba8e9ae 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java @@ -275,14 +275,14 @@ public class QRCodeScannerControllerTest extends SysuiTestCase { setUpLocal(/* deviceConfigActivity */ null, /* defaultActivity */ "abc/.def", /* validateActivity */ true, /* enableSetting */true, /* enableOnLockScreen */ true); - mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0", + mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 0, UserHandle.USER_CURRENT); - mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0", + mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 0, UserHandle.USER_CURRENT); - mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1", + mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 1, UserHandle.USER_CURRENT); - mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1", + mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 1, UserHandle.USER_CURRENT); // Once from setup + twice from this function verify(mCallback, times(3)).onQRCodeScannerPreferenceChanged(); @@ -297,14 +297,14 @@ public class QRCodeScannerControllerTest extends SysuiTestCase { assertThat(mController.isEnabledForLockScreenButton()).isTrue(); assertThat(mController.isAbleToLaunchScannerActivity()).isTrue(); - mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0", + mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 0, UserHandle.USER_CURRENT); verifyActivityDetails("abc/.def"); assertThat(mController.isEnabledForLockScreenButton()).isTrue(); assertThat(mController.isAllowedOnLockScreen()).isTrue(); assertThat(mController.isAbleToLaunchScannerActivity()).isTrue(); - mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1", + mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 1, UserHandle.USER_CURRENT); verifyActivityDetails("abc/.def"); assertThat(mController.isEnabledForLockScreenButton()).isTrue(); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt index 858ed6a6b54a..473d7b6d0dfa 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt @@ -22,8 +22,8 @@ import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.systemui.Flags import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat @@ -64,7 +64,7 @@ class UserSettingObserverTest(flags: FlagsParameterization) : SysuiTestCase() { mSetFlagsRule.setFlagsParameterization(flags) } - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private lateinit var testableLooper: TestableLooper @@ -85,7 +85,7 @@ class UserSettingObserverTest(flags: FlagsParameterization) : SysuiTestCase() { Handler(testableLooper.looper), TEST_SETTING, USER, - DEFAULT_VALUE + DEFAULT_VALUE, ) { override fun handleValueChanged(value: Int, observedChange: Boolean) { callback(value, observedChange) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt index 053a59aa533a..5f8adf0a3292 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt @@ -32,12 +32,12 @@ import com.android.systemui.qs.pipeline.data.repository.FakeInstalledTilesCompon import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesRepository import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.fakeQSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.fakeQSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider import com.android.systemui.settings.userTracker import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat @@ -58,12 +58,7 @@ class EditTilesListInteractorTest : SysuiTestCase() { private val batteryTileConfig = kosmos.qsBatterySaverTileConfig private val serviceInfo = - FakeInstalledTilesComponentRepository.ServiceInfo( - component, - tileName, - icon, - appName, - ) + FakeInstalledTilesComponentRepository.ServiceInfo(component, tileName, icon, appName) private val underTest = with(kosmos) { @@ -79,7 +74,7 @@ class EditTilesListInteractorTest : SysuiTestCase() { with(kosmos) { fakeInstalledTilesRepository.setInstalledServicesForUser( userTracker.userId, - listOf(serviceInfo) + listOf(serviceInfo), ) with(fakeQSTileConfigProvider) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt index 9d2528dbc64f..530ca9590532 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt @@ -22,7 +22,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.AIRPLANE_MODE_TILE_SPEC import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.HOTSPOT_TILE_SPEC import com.android.systemui.statusbar.policy.PolicyModule.Companion.WORK_MODE_TILE_SPEC @@ -38,61 +38,72 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) @SmallTest class NewTilesAvailabilityInteractorTest : SysuiTestCase() { - private val kosmos = testKosmos().apply { - tileAvailabilityInteractorsMap = buildMap { - put(AIRPLANE_MODE_TILE_SPEC, QSTileAvailabilityInteractor.AlwaysAvailableInteractor) - put(WORK_MODE_TILE_SPEC, FakeTileAvailabilityInteractor( - mapOf( - fakeUserRepository.getSelectedUserInfo().id to flowOf(true), - ).withDefault { flowOf(false) } - )) - put(HOTSPOT_TILE_SPEC, FakeTileAvailabilityInteractor( - emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) } - )) + private val kosmos = + testKosmos().apply { + tileAvailabilityInteractorsMap = buildMap { + put(AIRPLANE_MODE_TILE_SPEC, QSTileAvailabilityInteractor.AlwaysAvailableInteractor) + put( + WORK_MODE_TILE_SPEC, + FakeTileAvailabilityInteractor( + mapOf(fakeUserRepository.getSelectedUserInfo().id to flowOf(true)) + .withDefault { flowOf(false) } + ), + ) + put( + HOTSPOT_TILE_SPEC, + FakeTileAvailabilityInteractor( + emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) } + ), + ) + } } - } private val underTest by lazy { kosmos.newTilesAvailabilityInteractor } @Test - fun defaultUser_getAvailabilityFlow() = with(kosmos) { - testScope.runTest { - val availability by collectLastValue(underTest.newTilesAvailable) + fun defaultUser_getAvailabilityFlow() = + with(kosmos) { + testScope.runTest { + val availability by collectLastValue(underTest.newTilesAvailable) - assertThat(availability).isEqualTo( - mapOf( + assertThat(availability) + .isEqualTo( + mapOf( TileSpec.create(AIRPLANE_MODE_TILE_SPEC) to true, TileSpec.create(WORK_MODE_TILE_SPEC) to true, TileSpec.create(HOTSPOT_TILE_SPEC) to false, + ) ) - ) + } } - } @Test - fun getAvailabilityFlow_userChange() = with(kosmos) { - testScope.runTest { - val availability by collectLastValue(underTest.newTilesAvailable) - fakeUserRepository.asMainUser() + fun getAvailabilityFlow_userChange() = + with(kosmos) { + testScope.runTest { + val availability by collectLastValue(underTest.newTilesAvailable) + fakeUserRepository.asMainUser() - assertThat(availability).isEqualTo( - mapOf( + assertThat(availability) + .isEqualTo( + mapOf( TileSpec.create(AIRPLANE_MODE_TILE_SPEC) to true, TileSpec.create(WORK_MODE_TILE_SPEC) to false, TileSpec.create(HOTSPOT_TILE_SPEC) to false, + ) ) - ) + } } - } @Test - fun noAvailabilityInteractor_emptyMap() = with(kosmos) { - testScope.runTest { - tileAvailabilityInteractorsMap = emptyMap() + fun noAvailabilityInteractor_emptyMap() = + with(kosmos) { + testScope.runTest { + tileAvailabilityInteractorsMap = emptyMap() - val availability by collectLastValue(underTest.newTilesAvailable) + val availability by collectLastValue(underTest.newTilesAvailable) - assertThat(availability).isEmpty() + assertThat(availability).isEmpty() + } } - } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt index 67fb1003a6ce..7743c2c05574 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt @@ -28,7 +28,7 @@ import com.android.systemui.qs.FakeQSFactory import com.android.systemui.qs.FakeQSTile import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.qsTileFactory -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.AIRPLANE_MODE_TILE_SPEC import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.HOTSPOT_TILE_SPEC import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.INTERNET_TILE_SPEC diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt index 50229eb4348d..71ab0a2e4265 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt @@ -49,6 +49,9 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.pipeline.shared.metricSpec import com.android.systemui.qs.qsTileFactory import com.android.systemui.qs.shared.model.TileCategory +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.fakeQSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig @@ -56,9 +59,6 @@ import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig import com.android.systemui.qs.tiles.impl.sensorprivacy.qsCameraSensorPrivacyToggleTileConfig import com.android.systemui.qs.tiles.impl.sensorprivacy.qsMicrophoneSensorPrivacyToggleTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.fakeQSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider import com.android.systemui.settings.userTracker import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt index 00490427f80b..a2829b5f42cd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt @@ -27,7 +27,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.pipeline.data.model.RestoreData import com.android.systemui.qs.pipeline.data.model.RestoreProcessor import com.android.systemui.qs.pipeline.data.model.workTileRestoreProcessor @@ -36,6 +35,7 @@ import com.android.systemui.qs.pipeline.domain.model.AutoAddTracking import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.WorkModeTile import com.android.systemui.settings.FakeUserTracker +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -47,7 +47,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class WorkTileAutoAddableTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val restoreProcessor: RestoreProcessor get() = kosmos.workTileRestoreProcessor @@ -62,7 +62,7 @@ class WorkTileAutoAddableTest : SysuiTestCase() { FakeUserTracker( _userId = USER_INFO_0.id, _userInfo = USER_INFO_0, - _userProfiles = listOf(USER_INFO_0) + _userProfiles = listOf(USER_INFO_0), ) underTest = WorkTileAutoAddable(userTracker, kosmos.workTileRestoreProcessor) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt index 5bde7ad27b7a..12f1e66c71e5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt @@ -49,7 +49,7 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger import com.android.systemui.qs.pipeline.shared.logging.qsLogger import com.android.systemui.qs.qsTileFactory -import com.android.systemui.qs.tiles.di.newQSTileFactory +import com.android.systemui.qs.tiles.base.ui.model.newQSTileFactory import com.android.systemui.qs.toProto import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt index 3a9c3d066b23..4e0adcab8ea3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt @@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.FakeQSFactory @@ -39,6 +38,7 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.qsTileFactory import com.android.systemui.settings.fakeUserTracker import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -55,22 +55,12 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class NoLowNumberOfTilesTest : SysuiTestCase() { - private val USER_0_INFO = - UserInfo( - 0, - "zero", - "", - UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL, - ) + private val USER_0_INFO = UserInfo(0, "zero", "", UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL) - private val defaultTiles = - listOf( - TileSpec.create("internet"), - TileSpec.create("bt"), - ) + private val defaultTiles = listOf(TileSpec.create("internet"), TileSpec.create("bt")) private val kosmos = - Kosmos().apply { + testKosmos().apply { fakeMinimumTilesRepository = MinimumTilesFixedRepository(minNumberOfTiles = 2) fakeUserTracker.set(listOf(USER_0_INFO), 0) qsTileFactory = FakeQSFactory(::tileCreator) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt index 9d9bfda99bd9..77030aceb477 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt @@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.FakeQSFactory @@ -34,6 +33,7 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.qsTileFactory import com.android.systemui.settings.fakeUserTracker import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent @@ -52,7 +52,9 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class WorkProfileAutoAddedAfterRestoreTest : SysuiTestCase() { - private val kosmos by lazy { Kosmos().apply { fakeUserTracker.set(listOf(USER_0_INFO), 0) } } + private val kosmos by lazy { + testKosmos().apply { fakeUserTracker.set(listOf(USER_0_INFO), 0) } + } // Getter here so it can change when there is a managed profile. private val workTileAvailable: Boolean get() = hasManagedProfile() @@ -143,30 +145,15 @@ class WorkProfileAutoAddedAfterRestoreTest : SysuiTestCase() { } private fun TestScope.createManagedProfileAndAdd() { - kosmos.fakeUserTracker.set( - listOf(USER_0_INFO, MANAGED_USER_INFO), - 0, - ) + kosmos.fakeUserTracker.set(listOf(USER_0_INFO, MANAGED_USER_INFO), 0) runCurrent() } private companion object { val WORK_TILE_SPEC = "work".toTileSpec() - val USER_0_INFO = - UserInfo( - 0, - "zero", - "", - UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL, - ) + val USER_0_INFO = UserInfo(0, "zero", "", UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL) val MANAGED_USER_INFO = - UserInfo( - 10, - "ten-managed", - "", - 0, - UserManager.USER_TYPE_PROFILE_MANAGED, - ) + UserInfo(10, "ten-managed", "", 0, UserManager.USER_TYPE_PROFILE_MANAGED) fun String.toTileSpec() = TileSpec.create(this) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt index 1adba6fcd45d..6e5a700dde7f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt @@ -38,14 +38,14 @@ import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig import com.android.systemui.res.R import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor @@ -184,12 +184,12 @@ class ModesDndTileTest : SysuiTestCase() { state = Tile.STATE_INACTIVE secondaryLabel = "Old secondary label" } - val model = ModesDndTileModel(isActivated = true) + val model = ModesDndTileModel(isActivated = true, extraStatus = "Until 14:30") underTest.handleUpdateState(tileState, model) assertThat(tileState.state).isEqualTo(Tile.STATE_ACTIVE) - assertThat(tileState.secondaryLabel).isEqualTo("On") + assertThat(tileState.secondaryLabel).isEqualTo("Until 14:30") } @Test @@ -206,6 +206,6 @@ class ModesDndTileTest : SysuiTestCase() { underTest.handleUpdateState(tileState, null) assertThat(tileState.state).isEqualTo(Tile.STATE_ACTIVE) - assertThat(tileState.secondaryLabel).isEqualTo("On") + assertThat(tileState.secondaryLabel).isEqualTo(null) // Tile will use default On text } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt index bbc0dbcad355..c218a1b4ceb9 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt @@ -37,14 +37,14 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel -import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig +import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper import com.android.systemui.res.R import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerTest.kt index 02a81419ea78..94449637ebe7 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.actions +package com.android.systemui.qs.tiles.base.domain.actions import android.app.PendingIntent import android.content.ComponentName @@ -119,7 +119,7 @@ class QSTileIntentUserInputHandlerTest : SysuiTestCase() { .postStartActivityDismissingKeyguard( argThat(IntentMatcher(expectedIntent)), eq(0), - any() + any(), ) } @@ -149,7 +149,7 @@ class QSTileIntentUserInputHandlerTest : SysuiTestCase() { packageManager.queryIntentActivitiesAsUser( any(Intent::class.java), any(ResolveInfoFlags::class.java), - eq(user.identifier) + eq(user.identifier), ) ) .thenReturn(infos.map { ResolveInfo().apply { activityInfo = it } }) @@ -157,6 +157,7 @@ class QSTileIntentUserInputHandlerTest : SysuiTestCase() { private class IntentMatcher(intent: Intent) : ArgumentMatcher<Intent> { private val expectedIntent = intent + override fun matches(argument: Intent?): Boolean { return argument?.action.equals(expectedIntent.action) && argument?.`package`.equals(expectedIntent.`package`) && diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorTest.kt index c0e5a9bc9990..5c2edc228d7e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import android.content.ComponentName import android.content.Context diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLoggerTest.kt index 6a33b5f58820..ec88f710c6ac 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLoggerTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.logging +package com.android.systemui.qs.tiles.base.shared.logging import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest @@ -26,8 +26,8 @@ import com.android.systemui.log.LogBufferFactory import com.android.systemui.log.LogcatEchoTrackerAlways import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderTest.kt index 40971a87480d..fd83895ed790 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import android.platform.test.annotations.EnabledOnRavenwood import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -34,7 +34,7 @@ class QSTileConfigProviderTest : SysuiTestCase() { private val underTest = createQSTileConfigProviderImpl( - mapOf(VALID_SPEC.spec to QSTileConfigTestBuilder.build { tileSpec = VALID_SPEC }), + mapOf(VALID_SPEC.spec to QSTileConfigTestBuilder.build { tileSpec = VALID_SPEC }) ) @Test @@ -66,11 +66,7 @@ class QSTileConfigProviderTest : SysuiTestCase() { private fun createQSTileConfigProviderImpl( configs: Map<String, QSTileConfig> - ): QSTileConfigProviderImpl = - QSTileConfigProviderImpl( - configs, - mock<QsEventLogger>(), - ) + ): QSTileConfigProviderImpl = QSTileConfigProviderImpl(configs, mock<QsEventLogger>()) private companion object { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsTest.kt index fd09e3ca4bb8..ee0f5cd56acf 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.analytics +package com.android.systemui.qs.tiles.base.ui.analytics import android.platform.test.annotations.EnabledOnRavenwood import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -23,8 +23,8 @@ import com.android.internal.logging.InstanceId import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.qs.QSEvent -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -57,7 +57,7 @@ class QSTileAnalyticsTest : SysuiTestCase() { eq(QSEvent.QS_ACTION_CLICK), eq(0), eq("test_spec"), - eq(InstanceId.fakeInstanceId(0)) + eq(InstanceId.fakeInstanceId(0)), ) } @@ -70,7 +70,7 @@ class QSTileAnalyticsTest : SysuiTestCase() { eq(QSEvent.QS_ACTION_LONG_PRESS), eq(0), eq("test_spec"), - eq(InstanceId.fakeInstanceId(0)) + eq(InstanceId.fakeInstanceId(0)), ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImplTest.kt index da3cebd24e6b..4ebd22abe60d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImplTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest @@ -23,16 +23,16 @@ import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.FakeTileDetailsViewModel -import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics -import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder -import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelTest.kt index 4e9b63517d6d..d2f8b07b31b8 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import android.os.UserHandle import android.platform.test.annotations.EnabledOnRavenwood @@ -26,14 +26,17 @@ import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectValues import com.android.systemui.qs.FakeTileDetailsViewModel -import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelImpl +import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.FakeSystemClock diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelUserInputTest.kt index 166e9500cff9..0f939a95261b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelUserInputTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest @@ -23,16 +23,21 @@ import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.FakeTileDetailsViewModel -import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION -import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION -import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelImpl +import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION +import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION_2 +import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION +import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq @@ -171,10 +176,7 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted( - listOf( - DISABLED_RESTRICTION, - FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2, - ) + listOf(DISABLED_RESTRICTION, DISABLED_RESTRICTION_2) ) } @@ -199,7 +201,7 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), - eq(FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2), + eq(DISABLED_RESTRICTION_2), ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt index fda75ca76cec..78756d6769d1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt @@ -22,7 +22,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt index d27e81039602..ce6bcdfe6b36 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt @@ -22,10 +22,10 @@ import android.telephony.TelephonyManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject.Companion.assertThat -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject.Companion.assertThat +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.longClick import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/AirplaneModeMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapperTest.kt index 557f4ea262a3..ccb238626786 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/AirplaneModeMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl +package com.android.systemui.qs.tiles.impl.airplane.ui.mapper import android.graphics.drawable.TestStubDrawable import android.service.quicksettings.Tile @@ -23,29 +23,28 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.airplane.domain.AirplaneModeMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) -class AirplaneModeMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() +class AirplaneModeTileMapperTest : SysuiTestCase() { + private val kosmos = testKosmos() private val airplaneModeConfig = kosmos.qsAirplaneModeTileConfig - private lateinit var mapper: AirplaneModeMapper + private lateinit var mapper: AirplaneModeTileMapper @Before fun setup() { mapper = - AirplaneModeMapper( + AirplaneModeTileMapper( context.orCreateTestableResources .apply { addOverride(R.drawable.qs_airplane_icon_off, TestStubDrawable()) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt index afbc3e810743..5fb0ea666813 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt @@ -25,7 +25,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt index be2da174250b..e7dd145cecc5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt @@ -22,9 +22,9 @@ import android.provider.AlarmClock import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapperTest.kt index 24e46686e23d..9b1d0a5a0b58 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.alarm.domain +package com.android.systemui.qs.tiles.impl.alarm.ui.mapper import android.app.AlarmManager import android.graphics.drawable.TestStubDrawable @@ -23,12 +23,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.android.systemui.util.time.FakeSystemClock import java.time.Instant import java.time.LocalDateTime @@ -41,7 +41,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class AlarmTileMapperTest : SysuiTestCase() { private val oneMinute = 60000L - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val alarmTileConfig = kosmos.qsAlarmTileConfig private val fakeClock = FakeSystemClock() // Using lazy (versus =) to make sure we override the right context -- see b/311612168 diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt index 44c175ab7156..8d3f8d4b4166 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt @@ -23,10 +23,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileDataInteractor +import com.android.systemui.testKosmos import com.android.systemui.utils.leaks.FakeBatteryController import com.google.common.truth.Truth import kotlinx.coroutines.flow.flowOf @@ -40,7 +40,7 @@ import org.junit.runner.RunWith @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class BatterySaverTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val batteryController = FakeBatteryController(LeakCheck()) private val testUser = UserHandle.of(1) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt index 62c51e6252ce..68a4d4131086 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt @@ -22,9 +22,9 @@ import android.testing.LeakCheck import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileUserActionInteractor import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel import com.android.systemui.utils.leaks.FakeBatteryController diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapperTest.kt index 2ddaddd5ad35..8128c0c75043 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.battery.ui +package com.android.systemui.qs.tiles.impl.battery.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -22,12 +22,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -35,7 +35,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class BatterySaverTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val batterySaverTileConfig = kosmos.qsBatterySaverTileConfig private lateinit var mapper: BatterySaverTileMapper diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt index 4c156b77132b..4819539f4a80 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt @@ -23,7 +23,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeColorCorrectionRepository import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt index 0cf3734dd92b..90533f518259 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt @@ -24,9 +24,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeColorCorrectionRepository import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapperTest.kt index a3c159820a94..124e013ba784 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.colorcorrection.domain +package com.android.systemui.qs.tiles.impl.colorcorrection.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -22,19 +22,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel import com.android.systemui.qs.tiles.impl.colorcorrection.qsColorCorrectionTileConfig -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ColorCorrectionTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val colorCorrectionTileConfig = kosmos.qsColorCorrectionTileConfig private val subtitleArray by lazy { context.resources.getStringArray(R.array.tile_states_color_correction) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepositoryTest.kt index 10530a25b06e..80e865de43e7 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepositoryTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom +package com.android.systemui.qs.tiles.impl.custom.data.repository import android.content.ComponentName import android.content.Context @@ -25,9 +25,7 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults -import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository -import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepositoryImpl +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.whenever @@ -199,6 +197,7 @@ class CustomTileDefaultsRepositoryTest : SysuiTestCase() { appInfoIcon = APP_INFO_ICON_1, isSystemApp = isSystemApp, ) + private fun PackageManager.setupApp2(isSystemApp: Boolean = false) = setupApp( componentName = COMPONENT_NAME_2, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepositoryTest.kt index 835dba21ce05..93dcf7d2e80b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepositoryTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom +package com.android.systemui.qs.tiles.impl.custom.data.repository import android.annotation.SuppressLint import android.content.BroadcastReceiver @@ -28,8 +28,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository -import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepositoryImpl import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq @@ -111,7 +109,7 @@ class CustomTilePackageUpdatesRepositoryTest : SysuiTestCase() { any(), any(), nullable(), - nullable() + nullable(), ) listenerCaptor.value.onReceive(mockedContext, Intent(Intent.ACTION_MAIN)) runCurrent() @@ -144,9 +142,9 @@ class CustomTilePackageUpdatesRepositoryTest : SysuiTestCase() { type = IntentFilter.SCHEME_PACKAGE putExtra( Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, - arrayOf(componentName.packageName) + arrayOf(componentName.packageName), ) - } + }, ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt index 83e61d1b36bf..f8489c17a69c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt @@ -24,16 +24,16 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.qs.external.TileServiceKey import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat -import com.android.systemui.qs.tiles.impl.custom.commons.copy import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.customTileStatePersister -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import com.android.systemui.qs.tiles.impl.custom.packageManagerAdapterFacade +import com.android.systemui.qs.tiles.impl.custom.shared.model.copy +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runCurrent @@ -45,7 +45,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class CustomTileRepositoryTest : SysuiTestCase() { - private val kosmos = Kosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) } + private val kosmos = testKosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) } private val underTest: CustomTileRepository = with(kosmos) { CustomTileRepositoryImpl( @@ -213,7 +213,7 @@ class CustomTileRepositoryTest : SysuiTestCase() { underTest.updateWithTile( TEST_USER_1, Tile().apply { subtitle = "test_subtitle" }, - true + true, ) runCurrent() @@ -247,7 +247,7 @@ class CustomTileRepositoryTest : SysuiTestCase() { underTest.updateWithTile( TEST_USER_1, Tile().apply { subtitle = "test_subtitle" }, - true + true, ) runCurrent() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt index 2cc3678c2065..8e106490591b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt @@ -31,7 +31,7 @@ import com.android.systemui.qs.external.iQSTileService import com.android.systemui.qs.external.tileServiceManagerFacade import com.android.systemui.qs.external.tileServicesFacade import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat import com.android.systemui.qs.tiles.impl.custom.customTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.customTileInteractor @@ -39,7 +39,7 @@ import com.android.systemui.qs.tiles.impl.custom.customTilePackagesUpdatesReposi import com.android.systemui.qs.tiles.impl.custom.customTileRepository import com.android.systemui.qs.tiles.impl.custom.customTileServiceInteractor import com.android.systemui.qs.tiles.impl.custom.customTileSpec -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import com.android.systemui.qs.tiles.impl.custom.qsTileLogger import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt index a317dc525df9..6fef9f1da3af 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt @@ -33,7 +33,7 @@ import com.android.systemui.qs.tiles.impl.custom.customTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.customTileRepository import com.android.systemui.qs.tiles.impl.custom.customTileSpec import com.android.systemui.qs.tiles.impl.custom.customTileStatePersister -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.first diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt index 72e5766e409a..df4f097c8a8d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt @@ -38,14 +38,14 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.qs.external.componentName import com.android.systemui.qs.external.iQSTileService import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.intentInputs -import com.android.systemui.qs.tiles.base.actions.pendingIntentInputs -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.intentInputs +import com.android.systemui.qs.tiles.base.domain.actions.pendingIntentInputs +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.longClick import com.android.systemui.qs.tiles.impl.custom.customTileServiceInteractor import com.android.systemui.qs.tiles.impl.custom.customTileSpec -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel import com.android.systemui.qs.tiles.impl.custom.qsTileLogger import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository @@ -144,7 +144,7 @@ class CustomTileUserActionInteractorTest : SysuiTestCase() { assertThat( intent.getParcelableExtra( Intent.EXTRA_COMPONENT_NAME, - ComponentName::class.java + ComponentName::class.java, ) ) .isEqualTo(componentName) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapperTest.kt index 608adf183163..41f687251a0b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.domain.interactor +package com.android.systemui.qs.tiles.impl.custom.ui.mapper import android.app.IUriGrantsManager import android.content.ComponentName @@ -32,12 +32,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.assertThat +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject.Companion.assertThat import com.android.systemui.qs.tiles.impl.custom.customTileQsTileConfig import com.android.systemui.qs.tiles.impl.custom.customTileSpec -import com.android.systemui.qs.tiles.impl.custom.domain.CustomTileMapper -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt index d42eb5ebc9ab..5df7ae348e4b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt @@ -24,7 +24,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel import com.android.systemui.utils.leaks.FakeFlashlightController import com.google.common.truth.Truth.assertThat @@ -57,6 +57,7 @@ class FlashlightTileDataInteractorTest : SysuiTestCase() { assertThat(availability).isTrue() } + @Test fun availabilityOffMatchesController() = runTest { controller.hasFlashlight = false diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt index 1f19c98a93a3..d7536dcc32e1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt @@ -20,7 +20,7 @@ import android.app.ActivityManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel import com.android.systemui.statusbar.policy.FlashlightController import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapperTest.kt index a115c1235210..aebc67b9ce5d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.flashlight.domain +package com.android.systemui.qs.tiles.impl.flashlight.ui.mapper import android.graphics.drawable.TestStubDrawable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.tiles.base.shared.model.QSTileState import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertEquals import org.junit.Test @@ -34,7 +34,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class FlashlightMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileConfig = kosmos.qsFlashlightTileConfig private val mapper by lazy { FlashlightMapper( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt index cd825045de44..585c1a7c5e3f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt @@ -22,7 +22,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.google.common.truth.Truth import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt index 9bd4895ac21c..11b9f7712e2b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt @@ -26,17 +26,17 @@ import com.android.systemui.accessibility.fontscaling.FontScalingDialogDelegate import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.animation.Expandable import com.android.systemui.animation.LaunchableView -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.ActivityStarter import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.intentInputs -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.intentInputs +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel import com.android.systemui.statusbar.phone.FakeKeyguardStateController import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before @@ -67,7 +67,7 @@ class FontScalingUserActionInteractorTest : SysuiTestCase() { @Captor private lateinit var argumentCaptor: ArgumentCaptor<Runnable> - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val scope = kosmos.testScope private val qsTileIntentUserActionHandler = FakeQSTileIntentUserInputHandler() private val keyguardStateController = FakeKeyguardStateController() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapperTest.kt index 8f8f7105415f..1e794f917cb9 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.fontscaling.domain +package com.android.systemui.qs.tiles.impl.fontscaling.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -22,19 +22,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel import com.android.systemui.qs.tiles.impl.fontscaling.qsFontScalingTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class FontScalingTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val fontScalingTileConfig = kosmos.qsFontScalingTileConfig private val mapper by lazy { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt index 4b9d11d2f706..ae37684522fc 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt @@ -24,11 +24,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.hearingaid.HearingDevicesChecker import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel import com.android.systemui.statusbar.policy.fakeBluetoothController +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent @@ -46,7 +46,7 @@ import org.mockito.kotlin.whenever @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class HearingDevicesTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val testUser = UserHandle.of(1) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt index 1b497a2b36ed..5ab728f6e9e3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt @@ -22,13 +22,13 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogManager import com.android.systemui.accessibility.hearingaid.HearingDevicesUiEventLogger.Companion.LAUNCH_SOURCE_QS_TILE -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before @@ -47,7 +47,7 @@ import org.mockito.kotlin.whenever @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class HearingDevicesTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val inputHandler = FakeQSTileIntentUserInputHandler() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapperTest.kt index 3d3447da15a1..b0129f0c060d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.hearingdevices.domain +package com.android.systemui.qs.tiles.impl.hearingdevices.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -21,19 +21,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel import com.android.systemui.qs.tiles.impl.hearingdevices.qsHearingDevicesTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class HearingDevicesTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileConfig = kosmos.qsHearingDevicesTileConfig private val mapper by lazy { HearingDevicesTileMapper( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt index 63607f1edd59..a8747e81a2e3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -29,10 +29,9 @@ import com.android.systemui.common.shared.model.Text.Companion.loadText import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.logcatTableLogBuffer -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel import com.android.systemui.res.R import com.android.systemui.statusbar.connectivity.WifiIcons @@ -54,6 +53,7 @@ import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkMode import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository +import com.android.systemui.testKosmos import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat @@ -67,7 +67,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class InternetTileDataInteractorTest : SysuiTestCase() { private val testUser = UserHandle.of(1) - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private lateinit var underTest: InternetTileDataInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt index 261e3de939f2..8b58e5674176 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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,14 +21,14 @@ import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.dialog.InternetDialogManager import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel import com.android.systemui.statusbar.connectivity.AccessPointController +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.nullable import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest @@ -44,7 +44,7 @@ import org.mockito.kotlin.verify @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class InternetTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val inputHandler = FakeQSTileIntentUserInputHandler() private lateinit var underTest: InternetTileUserActionInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapperTest.kt index 54a653df696f..da91f70173c6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.internet.domain +package com.android.systemui.qs.tiles.impl.internet.ui.mapper import android.graphics.drawable.TestStubDrawable import android.os.fakeExecutorHandler @@ -28,23 +28,23 @@ import com.android.systemui.common.shared.model.ContentDescription.Companion.loa import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text.Companion.loadText -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel import com.android.systemui.statusbar.pipeline.satellite.ui.model.SatelliteIconModel import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileIconModel +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class InternetTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val internetTileConfig = kosmos.qsInternetTileConfig private val handler = kosmos.fakeExecutorHandler private val mapper by lazy { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt index 228e99305926..70828d5d6ff8 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt @@ -23,7 +23,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeColorInversionRepository import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt index 3f77b86971e1..e4a1ce2766c1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt @@ -24,9 +24,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeColorInversionRepository import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapperTest.kt index 780d58c83e5b..509a178ffcc3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.inversion.domain +package com.android.systemui.qs.tiles.impl.inversion.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -22,20 +22,20 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.tileimpl.SubtitleArrayMapping -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel import com.android.systemui.qs.tiles.impl.inversion.qsColorInversionTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ColorInversionTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val colorInversionTileConfig = kosmos.qsColorInversionTileConfig private val subtitleArrayId = SubtitleArrayMapping.getSubtitleId(colorInversionTileConfig.tileSpec.spec) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractorTest.kt index 7562ac00e4a6..1ee6ac6ccea8 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.domain.interactor import android.os.Handler import android.os.UserHandle @@ -22,13 +22,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.settings.fakeUserFileManager import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos import com.android.systemui.util.settings.fakeGlobalSettings import com.google.common.truth.Truth import kotlinx.coroutines.flow.flowOf @@ -42,7 +42,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class IssueRecordingDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val userTracker = kosmos.userTracker private val userFileManager = kosmos.fakeUserFileManager private val testUser = UserHandle.of(1) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractorTest.kt index 9c2be899b8ca..2791b74f2483 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.domain.interactor import android.os.Handler import android.os.UserHandle @@ -22,15 +22,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.dialogTransitionAnimator -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.activityStarter import com.android.systemui.plugins.statusbar.statusBarStateController import com.android.systemui.qs.pipeline.domain.interactor.panelInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.recordissue.RecordIssueDialogDelegate import com.android.systemui.screenrecord.RecordingController @@ -39,6 +39,7 @@ import com.android.systemui.settings.userFileManager import com.android.systemui.settings.userTracker import com.android.systemui.statusbar.phone.KeyguardDismissUtil import com.android.systemui.statusbar.policy.keyguardStateController +import com.android.systemui.testKosmos import com.android.systemui.util.settings.fakeGlobalSettings import com.google.common.truth.Truth import kotlinx.coroutines.test.runTest @@ -56,7 +57,7 @@ class IssueRecordingUserActionInteractorTest : SysuiTestCase() { @Mock private lateinit var recordingController: RecordingController val user = UserHandle(1) - val kosmos = Kosmos().also { it.testCase = this } + val kosmos = testKosmos().also { it.testCase = this } private lateinit var userContextProvider: UserContextProvider private lateinit var underTest: IssueRecordingUserActionInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapperTest.kt index fa6d8bf4a317..e469330ab21c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,22 +14,23 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.ui.mapper import android.content.res.mainResources import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.qsEventLogger import com.android.systemui.qs.shared.model.TileCategory -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel import com.android.systemui.recordissue.RecordIssueModule import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.google.common.truth.Truth import org.junit.Test import org.junit.runner.RunWith @@ -37,7 +38,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class IssueRecordingMapperTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val uiConfig = QSTileUIConfig.Resource(R.drawable.qs_record_issue_icon_off, R.string.qs_record_issue_label) private val config = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractorTest.kt index 52ce95b1d742..9c527145b6b4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.location.interactor +package com.android.systemui.qs.tiles.impl.location.domain.interactor import android.os.UserHandle import android.platform.test.annotations.EnabledOnRavenwood @@ -24,8 +24,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel import com.android.systemui.utils.leaks.FakeLocationController import com.google.common.truth.Truth diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractorTest.kt index 8b21cb4a97d5..bd632531b62d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractorTest.kt @@ -14,24 +14,23 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.location.interactor +package com.android.systemui.qs.tiles.impl.location.domain.interactor import android.platform.test.annotations.EnabledOnRavenwood import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.intentInputs -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick -import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.intentInputs +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.longClick import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel import com.android.systemui.statusbar.phone.FakeKeyguardStateController import com.android.systemui.statusbar.policy.LocationController +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.coroutines.EmptyCoroutineContext import kotlinx.coroutines.test.runTest @@ -58,7 +57,7 @@ class LocationTileUserActionInteractorTest : SysuiTestCase() { @Before fun setup() { MockitoAnnotations.initMocks(this) - val kosmos = Kosmos() + val kosmos = testKosmos() underTest = LocationTileUserActionInteractor( EmptyCoroutineContext, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapperTest.kt index 4ebe23dcdef1..807e37339d3f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.location.domain +package com.android.systemui.qs.tiles.impl.location.ui.mapper import android.graphics.drawable.TestStubDrawable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.qs.tiles.base.shared.model.QSTileState import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel import com.android.systemui.qs.tiles.impl.location.qsLocationTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.google.common.truth.Truth import junit.framework.Assert import org.junit.Test @@ -34,7 +34,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class LocationTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileConfig = kosmos.qsLocationTileConfig private val mapper by lazy { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt index 23d7b86df875..588832046776 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt @@ -27,7 +27,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.testKosmos diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt index 0a35b428bbc9..4ef61d900460 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt @@ -26,9 +26,9 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.mainCoroutineContext import com.android.systemui.kosmos.testScope import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor @@ -79,7 +79,7 @@ class ModesDndTileUserActionInteractorTest : SysuiTestCase() { zenModeRepository.activateMode(MANUAL_DND) assertThat(dndMode?.isActive).isTrue() - underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(true))) + underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(true, null))) assertThat(dndMode?.isActive).isFalse() } @@ -90,7 +90,7 @@ class ModesDndTileUserActionInteractorTest : SysuiTestCase() { val dndMode by collectLastValue(zenModeInteractor.dndMode) assertThat(dndMode?.isActive).isFalse() - underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(false))) + underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(false, null))) assertThat(dndMode?.isActive).isTrue() } @@ -101,7 +101,7 @@ class ModesDndTileUserActionInteractorTest : SysuiTestCase() { zenModeRepository.activateMode(MANUAL_DND) runCurrent() - underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(true))) + underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(true, null))) QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput { assertThat(it.intent.`package`).isEqualTo(SETTINGS_PACKAGE) @@ -118,7 +118,7 @@ class ModesDndTileUserActionInteractorTest : SysuiTestCase() { zenModeRepository.deactivateMode(MANUAL_DND) runCurrent() - underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(false))) + underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(false, null))) QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput { assertThat(it.intent.`package`).isEqualTo(SETTINGS_PACKAGE) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt index 0b641cee29a2..1df2e1baf6aa 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt @@ -34,7 +34,7 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt index 24e4279642d8..9d0b26f7104c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt @@ -30,9 +30,9 @@ import com.android.systemui.common.shared.model.asIcon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.mainCoroutineContext import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt index 29f642a4325d..318ce0eaab35 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt @@ -23,10 +23,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig import com.android.systemui.res.R import com.google.common.truth.Truth.assertThat import org.junit.Test @@ -58,23 +58,36 @@ class ModesDndTileMapperTest : SysuiTestCase() { @Test fun map_inactiveState() { - val model = ModesDndTileModel(isActivated = false) + val model = ModesDndTileModel(isActivated = false, extraStatus = null) val state = underTest.map(config, model) assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.INACTIVE) assertThat((state.icon as Icon.Loaded).res).isEqualTo(R.drawable.qs_dnd_icon_off) - assertThat(state.secondaryLabel).isEqualTo("Off") + assertThat(state.secondaryLabel).isNull() // Will use default label for activationState } @Test fun map_activeState() { - val model = ModesDndTileModel(isActivated = true) + val model = ModesDndTileModel(isActivated = true, extraStatus = null) val state = underTest.map(config, model) assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE) assertThat((state.icon as Icon.Loaded).res).isEqualTo(R.drawable.qs_dnd_icon_on) - assertThat(state.secondaryLabel).isEqualTo("On") + assertThat(state.secondaryLabel).isNull() // Will use default label for activationState + } + + @Test + fun map_activeStateWithExtraStatus() { + val model = ModesDndTileModel(isActivated = true, extraStatus = "Until 14:00") + + val state = underTest.map(config, model) + + assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE) + assertThat((state.icon as Icon.Loaded).res).isEqualTo(R.drawable.qs_dnd_icon_on) + assertThat(state.secondaryLabel).isEqualTo("Until 14:00") + assertThat(state.contentDescription).isEqualTo("Do Not Disturb") + assertThat(state.stateDescription).isEqualTo("Until 14:00") } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapperTest.kt index d73044f6b479..e8a85f46d381 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.modes.ui +package com.android.systemui.qs.tiles.impl.modes.ui.mapper import android.app.Flags import android.graphics.drawable.TestStubDrawable @@ -23,10 +23,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.asIcon +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig import com.android.systemui.res.R import com.google.common.truth.Truth.assertThat import org.junit.Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt index a0aa2d4a9a6c..a5e2922ffb3d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt @@ -26,7 +26,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.NightDisplayRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.dagger.NightDisplayListenerModule -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.testKosmos import com.android.systemui.user.utils.UserScopedService import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock @@ -47,7 +47,7 @@ import org.mockito.ArgumentMatchers.anyInt @SmallTest @RunWith(AndroidJUnit4::class) class NightDisplayTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testUser = UserHandle.of(1)!! private val testStartTime = LocalTime.MIDNIGHT private val testEndTime = LocalTime.NOON diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt index adc8bcba5a5c..a0d0b2353585 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt @@ -26,12 +26,12 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.NightDisplayRepository import com.android.systemui.dagger.NightDisplayListenerModule -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.intentInputs -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.intentInputs +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.custom.qsTileLogger import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel +import com.android.systemui.testKosmos import com.android.systemui.user.utils.UserScopedService import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock @@ -51,7 +51,7 @@ import org.mockito.Mockito.verify @SmallTest @RunWith(AndroidJUnit4::class) class NightDisplayTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileIntentUserActionHandler = FakeQSTileIntentUserInputHandler() private val testUser = UserHandle.of(1) private val colorDisplayManager = @@ -89,7 +89,7 @@ class NightDisplayTileUserActionInteractorTest : SysuiTestCase() { NightDisplayTileUserActionInteractor( nightDisplayRepository, qsTileIntentUserActionHandler, - kosmos.qsTileLogger + kosmos.qsTileLogger, ) @Test @@ -143,7 +143,7 @@ class NightDisplayTileUserActionInteractorTest : SysuiTestCase() { underTest.handleInput( QSTileInputTestKtx.longClick( NightDisplayTileModel.AutoModeOff(enabledState, false), - testUser + testUser, ) ) @@ -163,7 +163,7 @@ class NightDisplayTileUserActionInteractorTest : SysuiTestCase() { underTest.handleInput( QSTileInputTestKtx.longClick( NightDisplayTileModel.AutoModeOff(enabledState, false), - testUser + testUser, ) ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapperTest.kt index 7c853261aa1c..25c70160fceb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.night.ui +package com.android.systemui.qs.tiles.impl.night.ui.mapper import android.graphics.drawable.TestStubDrawable import android.service.quicksettings.Tile @@ -24,13 +24,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel import com.android.systemui.qs.tiles.impl.night.qsNightDisplayTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import java.time.LocalTime import java.time.format.DateTimeFormatter @@ -41,7 +41,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class NightDisplayTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val config = kosmos.qsNightDisplayTileConfig private val testStartTime = LocalTime.MIDNIGHT diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt index 4786fc40562a..51cad304db33 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt @@ -24,9 +24,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toCollection @@ -38,12 +38,11 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class NotesTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val testUser = UserHandle.of(1) private lateinit var underTest: NotesTileDataInteractor - @EnableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE) @Test fun availability_qsFlagEnabled_notesRoleEnabled_returnTrue() = @@ -92,7 +91,7 @@ class NotesTileDataInteractorTest : SysuiTestCase() { fun tileData_notEmpty() = runTest { underTest = NotesTileDataInteractor(isNoteTaskEnabled = true) val flowValue by - collectLastValue(underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))) + collectLastValue(underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))) runCurrent() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt index 54911e612291..c29a490d23b5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt @@ -20,27 +20,27 @@ import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.notetask.NoteTaskController import com.android.systemui.notetask.NoteTaskEntryPoint import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.kotlin.mock import org.mockito.Mockito.verify +import org.mockito.kotlin.mock @SmallTest @RunWith(AndroidJUnit4::class) class NotesTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val inputHandler = FakeQSTileIntentUserInputHandler() private val panelInteractor = mock<PanelInteractor>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapperTest.kt index b6caa22a3012..0234584abda3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.notes.domain +package com.android.systemui.qs.tiles.impl.notes.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Button @@ -22,19 +22,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel import com.android.systemui.qs.tiles.impl.notes.qsNotesTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import kotlin.test.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class NotesTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileConfig = kosmos.qsNotesTileConfig private val mapper by lazy { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt index 59eb069a5f3b..d0ea6913aef4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt @@ -22,9 +22,9 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.oneHandedModeRepository import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileDataInteractor +import com.android.systemui.testKosmos import com.android.wm.shell.onehanded.OneHanded import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf @@ -37,7 +37,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class OneHandedModeTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testUser = UserHandle.of(1)!! private val oneHandedModeRepository = kosmos.oneHandedModeRepository private val underTest: OneHandedModeTileDataInteractor = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt index 3f17d4cec643..a8f1808ba6f4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt @@ -23,9 +23,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeOneHandedModeRepository -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileUserActionInteractor import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel import com.google.common.truth.Truth.assertThat @@ -42,11 +42,7 @@ class OneHandedModeTileUserActionInteractorTest : SysuiTestCase() { private val repository = FakeOneHandedModeRepository() private val inputHandler = FakeQSTileIntentUserInputHandler() - private val underTest = - OneHandedModeTileUserActionInteractor( - repository, - inputHandler, - ) + private val underTest = OneHandedModeTileUserActionInteractor(repository, inputHandler) @Test fun handleClickWhenEnabled() = runTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapperTest.kt index 5b39810e3477..fe10457b2103 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.onehanded.ui +package com.android.systemui.qs.tiles.impl.onehanded.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -22,13 +22,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.tileimpl.SubtitleArrayMapping -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel import com.android.systemui.qs.tiles.impl.onehanded.qsOneHandedModeTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -36,7 +36,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class OneHandedModeTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val config = kosmos.qsOneHandedModeTileConfig private val subtitleArrayId = SubtitleArrayMapping.getSubtitleId(config.tileSpec.spec) private val subtitleArray by lazy { context.resources.getStringArray(subtitleArrayId) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt index c41ce2f7854c..82535db6ab4e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt @@ -24,7 +24,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qrcodescanner.controller.QRCodeScannerController import com.android.systemui.qrcodescanner.controller.QRCodeScannerController.Callback -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt index 312f18029570..8c0dae80730c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt @@ -21,12 +21,12 @@ import android.platform.test.annotations.EnabledOnRavenwood import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel import com.android.systemui.qs.tiles.impl.qr.qrCodeScannerTileUserActionInteractor +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import kotlinx.coroutines.test.runTest import org.junit.Test @@ -36,7 +36,7 @@ import org.junit.runner.RunWith @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class QRCodeScannerTileUserActionInteractorTest : SysuiTestCase() { - val kosmos = Kosmos() + val kosmos = testKosmos() private val inputHandler = kosmos.qsTileIntentUserInputHandler private val underTest = kosmos.qrCodeScannerTileUserActionInteractor private val intent = mock<Intent>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapperTest.kt index c572ff60b61a..8e453caf296d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.qr.ui +package com.android.systemui.qs.tiles.impl.qr.ui.mapper import android.content.Intent import android.graphics.drawable.TestStubDrawable @@ -23,11 +23,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel import com.android.systemui.qs.tiles.impl.qr.qsQRCodeScannerTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import org.junit.Before import org.junit.Test @@ -36,7 +37,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class QRCodeScannerTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val config = kosmos.qsQRCodeScannerTileConfig private lateinit var mapper: QRCodeScannerTileMapper @@ -46,12 +47,7 @@ class QRCodeScannerTileMapperTest : SysuiTestCase() { mapper = QRCodeScannerTileMapper( context.orCreateTestableResources - .apply { - addOverride( - com.android.systemui.res.R.drawable.ic_qr_code_scanner, - TestStubDrawable(), - ) - } + .apply { addOverride(R.drawable.ic_qr_code_scanner, TestStubDrawable()) } .resources, context.theme, ) @@ -91,9 +87,9 @@ class QRCodeScannerTileMapperTest : SysuiTestCase() { val label = context.getString(com.android.systemui.res.R.string.qr_code_scanner_title) return QSTileState( Icon.Loaded( - context.getDrawable(com.android.systemui.res.R.drawable.ic_qr_code_scanner)!!, + context.getDrawable(R.drawable.ic_qr_code_scanner)!!, null, - com.android.systemui.res.R.drawable.ic_qr_code_scanner, + R.drawable.ic_qr_code_scanner, ), label, activationState, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt index dc3248d42d62..db46a4f3fc2f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt @@ -23,10 +23,10 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.reduceBrightColorsController import com.android.systemui.coroutines.collectValues -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent @@ -40,14 +40,14 @@ import org.junit.runner.RunWith class ReduceBrightColorsTileDataInteractorTest : SysuiTestCase() { private val isAvailable = true - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val reduceBrightColorsController = kosmos.reduceBrightColorsController private val underTest: ReduceBrightColorsTileDataInteractor = ReduceBrightColorsTileDataInteractor( testScope.testScheduler, isAvailable, - reduceBrightColorsController + reduceBrightColorsController, ) @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt index 75b090c4034b..221a6f17bed0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt @@ -28,11 +28,11 @@ import com.android.server.display.feature.flags.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.extradim.ExtraDimDialogManager import com.android.systemui.accessibility.reduceBrightColorsController -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before @@ -48,7 +48,7 @@ import org.mockito.kotlin.verify @RunWith(AndroidJUnit4::class) class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val inputHandler = FakeQSTileIntentUserInputHandler() private val controller = kosmos.reduceBrightColorsController diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapperTest.kt index 00017f9059de..dabf0b025281 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.reducebrightness.ui +package com.android.systemui.qs.tiles.impl.reducebrightness.ui.mapper import android.graphics.drawable.TestStubDrawable import android.service.quicksettings.Tile @@ -23,12 +23,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel import com.android.systemui.qs.tiles.impl.reducebrightness.qsReduceBrightColorsTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -36,7 +36,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ReduceBrightColorsTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val config = kosmos.qsReduceBrightColorsTileConfig private lateinit var mapper: ReduceBrightColorsTileMapper diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt index 283fa601f8df..ef67910f8799 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt @@ -28,9 +28,9 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.camera.data.repository.fakeCameraAutoRotateRepository import com.android.systemui.camera.data.repository.fakeCameraSensorPrivacyRepository import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.whenever import com.android.systemui.utils.leaks.FakeBatteryController @@ -48,7 +48,7 @@ import org.junit.runner.RunWith @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class RotationLockTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val batteryController = FakeBatteryController(LeakCheck()) private val rotationController = FakeRotationLockController(LeakCheck()) @@ -65,7 +65,7 @@ class RotationLockTileDataInteractorTest : SysuiTestCase() { whenever( packageManager.checkPermission( eq(Manifest.permission.CAMERA), - eq(TEST_PACKAGE_NAME) + eq(TEST_PACKAGE_NAME), ) ) .thenReturn(PackageManager.PERMISSION_GRANTED) @@ -81,7 +81,7 @@ class RotationLockTileDataInteractorTest : SysuiTestCase() { .apply { addOverride(com.android.internal.R.bool.config_allowRotationResolver, true) } - .resources + .resources, ) } @@ -182,7 +182,7 @@ class RotationLockTileDataInteractorTest : SysuiTestCase() { whenever( packageManager.checkPermission( eq(Manifest.permission.CAMERA), - eq(TEST_PACKAGE_NAME) + eq(TEST_PACKAGE_NAME), ) ) .thenReturn(PackageManager.PERMISSION_DENIED) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt index 1653ce369ea1..e60e2106e556 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt @@ -22,9 +22,9 @@ import android.testing.LeakCheck import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel import com.android.systemui.utils.leaks.FakeRotationLockController import com.google.common.truth.Truth.assertThat @@ -39,11 +39,7 @@ class RotationLockTileUserActionInteractorTest : SysuiTestCase() { private val controller = FakeRotationLockController(LeakCheck()) private val inputHandler = FakeQSTileIntentUserInputHandler() - private val underTest = - RotationLockTileUserActionInteractor( - controller, - inputHandler, - ) + private val underTest = RotationLockTileUserActionInteractor(controller, inputHandler) @Test fun handleClickWhenEnabled() = runTest { @@ -69,14 +65,7 @@ class RotationLockTileUserActionInteractorTest : SysuiTestCase() { fun handleLongClickWhenDisabled() = runTest { val enabled = false - underTest.handleInput( - QSTileInputTestKtx.longClick( - RotationLockTileModel( - enabled, - false, - ) - ) - ) + underTest.handleInput(QSTileInputTestKtx.longClick(RotationLockTileModel(enabled, false))) QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput { assertThat(it.intent.action).isEqualTo(Settings.ACTION_AUTO_ROTATE_SETTINGS) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt index 74010143166b..92c7a1ea76a2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt @@ -25,14 +25,14 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.defaultDeviceState import com.android.systemui.deviceStateManager import com.android.systemui.foldedDeviceStateList -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel import com.android.systemui.qs.tiles.impl.rotation.qsRotationLockTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.statusbar.policy.DevicePostureController import com.android.systemui.statusbar.policy.devicePostureController +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test @@ -42,7 +42,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class RotationLockTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val rotationLockTileConfig = kosmos.qsRotationLockTileConfig private val devicePostureController = kosmos.devicePostureController private val deviceStateManager = kosmos.deviceStateManager diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt index c286ea7a5062..97bd199780a0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt @@ -24,7 +24,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel import com.android.systemui.utils.leaks.FakeDataSaverController import com.google.common.truth.Truth diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt index 87ac034a6316..ee57b25a15ed 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt @@ -24,9 +24,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogTransitionAnimator -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.intentInputs -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.intentInputs +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel import com.android.systemui.settings.UserFileManager import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapperTest.kt index 1fb5048dd4c9..638b76d685f3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.saver.domain +package com.android.systemui.qs.tiles.impl.saver.ui.mapper import android.graphics.drawable.TestStubDrawable import android.widget.Switch @@ -22,19 +22,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel import com.android.systemui.qs.tiles.impl.saver.qsDataSaverTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class DataSaverTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val dataSaverTileConfig = kosmos.qsDataSaverTileConfig // Using lazy (versus =) to make sure we override the right context -- see b/311612168 diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt index 41174e7ca6af..0c98271a70fc 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt @@ -22,11 +22,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.screenRecordRepository +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent @@ -38,7 +38,7 @@ import org.junit.runner.RunWith @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) class ScreenRecordTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val screenRecordRepo = kosmos.screenRecordRepository private val underTest: ScreenRecordTileDataInteractor = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt index 778c73fd8638..9ffffa4b7669 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt @@ -26,16 +26,16 @@ import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.animation.Expandable import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepositoryImpl import com.android.systemui.statusbar.phone.KeyguardDismissUtil +import com.android.systemui.testKosmos import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith @@ -49,7 +49,7 @@ import org.mockito.kotlin.mock @SmallTest @RunWith(AndroidJUnit4::class) class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val keyguardInteractor = kosmos.keyguardInteractor private val dialogTransitionAnimator = mock<DialogTransitionAnimator>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/mapper/ScreenRecordTileMapperTest.kt index 363255695131..6acfc4441027 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/mapper/ScreenRecordTileMapperTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.screenrecord.ui +package com.android.systemui.qs.tiles.impl.screenrecord.ui.mapper import android.graphics.drawable.TestStubDrawable import android.text.TextUtils @@ -23,13 +23,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject -import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.ScreenRecordTileMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject +import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.mapper.ScreenRecordTileMapper import com.android.systemui.qs.tiles.impl.screenrecord.qsScreenRecordTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.screenrecord.data.model.ScreenRecordModel +import com.android.systemui.testKosmos import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -37,7 +37,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ScreenRecordTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val config = kosmos.qsScreenRecordTileConfig private lateinit var mapper: ScreenRecordTileMapper diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt index 6c7bb1b46c36..7d1d7d868c8e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt @@ -23,11 +23,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -44,7 +43,7 @@ import org.mockito.Mockito.verify @SmallTest @RunWith(AndroidJUnit4::class) class SensorPrivacyToggleTileDataInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val mockSensorPrivacyController = mock<IndividualSensorPrivacyController> { @@ -55,7 +54,7 @@ class SensorPrivacyToggleTileDataInteractorTest : SysuiTestCase() { SensorPrivacyToggleTileDataInteractor( testScope.testScheduler, mockSensorPrivacyController, - CAMERA + CAMERA, ) @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt index 562e6ebcc029..2630fddcbc88 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt @@ -26,14 +26,13 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor -import com.android.systemui.kosmos.Kosmos import com.android.systemui.plugins.activityStarter -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx -import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -48,7 +47,7 @@ import org.mockito.Mockito.verify @SmallTest @RunWith(AndroidJUnit4::class) class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val inputHandler = FakeQSTileIntentUserInputHandler() private val keyguardInteractor = kosmos.keyguardInteractor // The keyguard repository below is the same one kosmos used to create the interactor above @@ -64,7 +63,7 @@ class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() { mockActivityStarter, mockSensorPrivacyController, fakeSafetyCenterManager, - CAMERA + CAMERA, ) @Test @@ -79,7 +78,7 @@ class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() { .setSensorBlocked( eq(SensorPrivacyManager.Sources.QS_TILE), eq(CAMERA), - eq(!originalIsBlocked) + eq(!originalIsBlocked), ) } @@ -95,7 +94,7 @@ class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() { .setSensorBlocked( eq(SensorPrivacyManager.Sources.QS_TILE), eq(CAMERA), - eq(!originalIsBlocked) + eq(!originalIsBlocked), ) } @@ -114,7 +113,7 @@ class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() { .setSensorBlocked( eq(SensorPrivacyManager.Sources.QS_TILE), eq(CAMERA), - eq(!originalIsBlocked) + eq(!originalIsBlocked), ) verify(mockActivityStarter).postQSRunnableDismissingKeyguard(any()) } @@ -150,7 +149,7 @@ class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() { mockActivityStarter, mockSensorPrivacyController, fakeSafetyCenterManager, - MICROPHONE + MICROPHONE, ) micUserActionInteractor.handleInput( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapperTest.kt index e4cd0e0ec215..d9a30b235bb2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.sensorprivacy.ui +package com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper import android.graphics.drawable.TestStubDrawable import android.hardware.SensorPrivacyManager.Sensors.CAMERA @@ -24,22 +24,23 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel import com.android.systemui.qs.tiles.impl.sensorprivacy.qsCameraSensorPrivacyToggleTileConfig import com.android.systemui.qs.tiles.impl.sensorprivacy.qsMicrophoneSensorPrivacyToggleTileConfig -import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.CameraPrivacyTileResources -import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.MicrophonePrivacyTileResources -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources +import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources.CameraPrivacyTileResources +import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources.MicrophonePrivacyTileResources import com.android.systemui.res.R +import com.android.systemui.testKosmos import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class SensorPrivacyToggleTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val cameraConfig = kosmos.qsCameraSensorPrivacyToggleTileConfig private val micConfig = kosmos.qsMicrophoneSensorPrivacyToggleTileConfig diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractorTest.kt index 96538b730354..36a60c4157a2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.uimodenight.domain +package com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor import android.app.UiModeManager import android.content.res.Configuration @@ -27,9 +27,8 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor -import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel import com.android.systemui.statusbar.phone.ConfigurationControllerImpl import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.mockito.mock @@ -77,7 +76,7 @@ class UiModeNightTileDataInteractorTest : SysuiTestCase() { uiModeManager, batteryController, locationController, - dateFormatUtil + dateFormatUtil, ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractorTest.kt index eea6d161d4ff..894a6cb62ce5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.uimodenight.domain +package com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor import android.app.UiModeManager import android.platform.test.annotations.EnabledOnRavenwood @@ -22,11 +22,10 @@ import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.intentInputs -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.intentInputs +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.uimodenight.UiModeNightTileModelHelper.createModel -import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth @@ -57,7 +56,7 @@ class UiModeNightTileUserActionInteractorTest : SysuiTestCase() { UiModeNightTileUserActionInteractor( EmptyCoroutineContext, uiModeManager, - qsTileIntentUserActionHandler + qsTileIntentUserActionHandler, ) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapperTest.kt index 8f5f2d3e6689..e7653f238576 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapperTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.uimodenight.domain +package com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper import android.app.UiModeManager import android.graphics.drawable.TestStubDrawable @@ -25,12 +25,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.uimodenight.UiModeNightTileModelHelper.createModel import com.android.systemui.qs.tiles.impl.uimodenight.qsUiModeNightTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import kotlin.reflect.KClass import org.junit.Test import org.junit.runner.RunWith @@ -38,7 +38,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class UiModeNightTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileConfig = kosmos.qsUiModeNightTileConfig private val mapper by lazy { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt index 86513006cef1..4f594167cdfd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt @@ -23,7 +23,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel import com.android.systemui.utils.leaks.FakeManagedProfileController import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt index 8a63e2c8800f..3d08a01bc943 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt @@ -22,9 +22,9 @@ import android.testing.LeakCheck import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject -import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject +import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel import com.android.systemui.utils.leaks.FakeManagedProfileController import com.google.common.truth.Truth.assertThat @@ -40,11 +40,7 @@ class WorkModeTileUserActionInteractorTest : SysuiTestCase() { private val inputHandler = FakeQSTileIntentUserInputHandler() private val profileController = FakeManagedProfileController(LeakCheck()) - private val underTest = - WorkModeTileUserActionInteractor( - profileController, - inputHandler, - ) + private val underTest = WorkModeTileUserActionInteractor(profileController, inputHandler) @Test fun handleClickWhenEnabled() = runTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapperTest.kt index 2c81f39a03ec..b420d44c7ecc 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.work.ui +package com.android.systemui.qs.tiles.impl.work.ui.mapper import android.app.admin.DevicePolicyResources import android.app.admin.DevicePolicyResourcesManager @@ -26,12 +26,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon -import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel import com.android.systemui.qs.tiles.impl.work.qsWorkModeTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock @@ -43,7 +43,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class WorkModeTileMapperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val qsTileConfig = kosmos.qsWorkModeTileConfig private val devicePolicyManager = kosmos.devicePolicyManager private val testLabel = context.getString(R.string.quick_settings_work_mode_label) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt index a8b005fb6554..12ed3f0c96fe 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt @@ -30,7 +30,6 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorI import com.android.systemui.coroutines.collectLastValue import com.android.systemui.display.data.repository.displayStateRepository import com.android.systemui.dump.DumpManager -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope @@ -40,6 +39,7 @@ import com.android.systemui.qs.dagger.QSSceneComponent import com.android.systemui.settings.brightness.MirrorController import com.android.systemui.shade.data.repository.fakeShadeRepository import com.android.systemui.shade.domain.interactor.shadeModeInteractor +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.capture @@ -65,7 +65,7 @@ import org.mockito.Mockito.verify @RunWith(AndroidJUnit4::class) class QSSceneAdapterImplTest : SysuiTestCase() { - private val kosmos = Kosmos().apply { testCase = this@QSSceneAdapterImplTest } + private val kosmos = testKosmos().apply { testCase = this@QSSceneAdapterImplTest } private val testDispatcher = kosmos.testDispatcher private val testScope = kosmos.testScope diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt index 7bcaeabfee69..390a5d8efff1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt @@ -28,12 +28,12 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.animation.dialogTransitionAnimator import com.android.systemui.concurrency.fakeExecutor -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.settings.UserContextProvider import com.android.systemui.settings.userFileManager import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos import com.android.systemui.util.settings.fakeGlobalSettings import com.android.traceur.TraceConfig import com.google.common.truth.Truth @@ -52,7 +52,7 @@ import org.mockito.kotlin.verify @TestableLooper.RunWithLooper(setAsMainLooper = true) class IssueRecordingServiceSessionTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val bgExecutor = kosmos.fakeExecutor private val userContextProvider: UserContextProvider = kosmos.userTracker private val dialogTransitionAnimator: DialogTransitionAnimator = kosmos.dialogTransitionAnimator diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt index 83bdcd2161ee..0510e6ca3ced 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt @@ -22,9 +22,9 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.settings.userFileManager import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos import com.android.systemui.util.settings.fakeGlobalSettings import com.google.common.truth.Truth import org.junit.Before @@ -40,7 +40,7 @@ import org.mockito.kotlin.verify @TestableLooper.RunWithLooper(setAsMainLooper = true) class IssueRecordingStateTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private lateinit var underTest: IssueRecordingState @Mock private lateinit var resolver: ContentResolver diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt index 737b10166199..6f0dd16eacd4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt @@ -20,10 +20,10 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.settings.UserTracker import com.android.systemui.settings.userTracker +import com.android.systemui.testKosmos import com.google.common.truth.Truth import org.junit.Before import org.junit.Test @@ -34,7 +34,7 @@ import org.mockito.MockitoAnnotations @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class ScreenRecordingStartTimeStoreTest : SysuiTestCase() { - private val userTracker: UserTracker = Kosmos().also { it.testCase = this }.userTracker + private val userTracker: UserTracker = testKosmos().also { it.testCase = this }.userTracker private lateinit var underTest: ScreenRecordingStartTimeStore diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt index a82a7de75cc0..7e9487b04862 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt @@ -25,7 +25,6 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.shared.model.StatusBarState -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest @@ -38,6 +37,7 @@ import com.android.systemui.statusbar.notification.domain.interactor.activeNotif import com.android.systemui.statusbar.notification.headsup.HeadsUpManager import com.android.systemui.statusbar.notification.init.NotificationsController import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor +import com.android.systemui.testKosmos import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor @@ -57,7 +57,7 @@ import org.mockito.Mockito.verify @RunWith(AndroidJUnit4::class) class WindowRootViewVisibilityInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val testDispatcher = StandardTestDispatcher() private val iStatusBarService = mock<IStatusBarService>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt index 9724974e3044..bd5416676c8a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt @@ -21,10 +21,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -39,7 +39,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class ScreenRecordRepositoryTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val recordingController = mock<RecordingController>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt index c6ce58185cf0..0c90d077273d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt @@ -25,7 +25,6 @@ import com.android.internal.statusbar.IStatusBarService import com.android.systemui.SysuiTestCase import com.android.systemui.assist.AssistManager import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.log.LogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController @@ -43,6 +42,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.statusbar.window.StatusBarWindowControllerStore +import com.android.systemui.testKosmos import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -63,7 +63,7 @@ import org.mockito.MockitoAnnotations @SmallTest class ShadeControllerImplTest : SysuiTestCase() { private val executor = FakeExecutor(FakeSystemClock()) - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope @Mock private lateinit var commandQueue: CommandQueue diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt index 054c1b8207eb..32eec56af8ea 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt @@ -27,7 +27,6 @@ import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.scene.domain.interactor.sceneInteractor @@ -35,6 +34,7 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.MutableStateFlow @@ -52,7 +52,7 @@ import org.mockito.Mockito.verify @RunWith(AndroidJUnit4::class) @EnableSceneContainer class ShadeControllerSceneImplTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt index ddad230f04e9..2f2fafab53d5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt @@ -25,8 +25,8 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.PluginLifecycleManager import com.android.systemui.plugins.PluginListener import com.android.systemui.plugins.PluginManager +import com.android.systemui.plugins.clocks.ClockAxisStyle import com.android.systemui.plugins.clocks.ClockController -import com.android.systemui.plugins.clocks.ClockFontAxisSetting import com.android.systemui.plugins.clocks.ClockId import com.android.systemui.plugins.clocks.ClockMessageBuffers import com.android.systemui.plugins.clocks.ClockMetadata @@ -543,7 +543,7 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun jsonDeserialization_fontAxes() { - val expected = ClockSettings(axes = listOf(ClockFontAxisSetting("KEY", 10f))) + val expected = ClockSettings(axes = ClockAxisStyle("KEY", 10f)) val json = JSONObject("""{"axes":[{"key":"KEY","value":10}]}""") val actual = ClockSettings.fromJson(json) assertEquals(expected, actual) @@ -576,7 +576,7 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun jsonSerialization_axisSettings() { - val settings = ClockSettings(axes = listOf(ClockFontAxisSetting("KEY", 10f))) + val settings = ClockSettings(axes = ClockAxisStyle("KEY", 10f)) val actual = ClockSettings.toJson(settings) val expected = JSONObject("""{"metadata":{},"axes":[{"key":"KEY","value":10}]}""") assertEquals(expected.toString(), actual.toString()) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt index 17509dc6a80f..8e2d1b5a88f6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt @@ -3,64 +3,57 @@ package com.android.systemui.shared.condition import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.condition.testStart +import com.android.systemui.condition.testStop +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher -import kotlinx.coroutines.test.runTest -import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ConditionExtensionsTest : SysuiTestCase() { - private lateinit var testScope: TestScope - private val testCallback = - Condition.Callback { - // This is a no-op - } - - @Before - fun setUp() { - testScope = TestScope(UnconfinedTestDispatcher()) - } + private val kosmos = testKosmos() @Test fun flowInitiallyTrue() = - testScope.runTest { + kosmos.runTest { val flow = flowOf(true) - val condition = flow.toCondition(scope = this, Condition.START_EAGERLY) + val condition = flow.toCondition(scope = testScope, Condition.START_EAGERLY) assertThat(condition.isConditionSet).isFalse() - condition.testStart() + testStart(condition) assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isTrue() } @Test fun flowInitiallyFalse() = - testScope.runTest { + kosmos.runTest { val flow = flowOf(false) - val condition = flow.toCondition(scope = this, Condition.START_EAGERLY) + val condition = flow.toCondition(scope = testScope, Condition.START_EAGERLY) assertThat(condition.isConditionSet).isFalse() - condition.testStart() + testStart(condition) assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isFalse() } @Test fun emptyFlowWithNoInitialValue() = - testScope.runTest { + kosmos.runTest { val flow = emptyFlow<Boolean>() - val condition = flow.toCondition(scope = this, Condition.START_EAGERLY) - condition.testStop() + val condition = flow.toCondition(scope = testScope, Condition.START_EAGERLY) + testStop(condition) assertThat(condition.isConditionSet).isFalse() assertThat(condition.isConditionMet).isFalse() @@ -68,15 +61,15 @@ class ConditionExtensionsTest : SysuiTestCase() { @Test fun emptyFlowWithInitialValueOfTrue() = - testScope.runTest { + kosmos.runTest { val flow = emptyFlow<Boolean>() val condition = flow.toCondition( - scope = this, + scope = testScope, strategy = Condition.START_EAGERLY, initialValue = true, ) - condition.testStart() + testStart(condition) assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isTrue() @@ -84,15 +77,15 @@ class ConditionExtensionsTest : SysuiTestCase() { @Test fun emptyFlowWithInitialValueOfFalse() = - testScope.runTest { + kosmos.runTest { val flow = emptyFlow<Boolean>() val condition = flow.toCondition( - scope = this, + scope = testScope, strategy = Condition.START_EAGERLY, initialValue = false, ) - condition.testStart() + testStart(condition) assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isFalse() @@ -100,42 +93,36 @@ class ConditionExtensionsTest : SysuiTestCase() { @Test fun conditionUpdatesWhenFlowEmitsNewValue() = - testScope.runTest { + kosmos.runTest { val flow = MutableStateFlow(false) - val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY) - condition.testStart() + val condition = flow.toCondition(scope = testScope, strategy = Condition.START_EAGERLY) + testStart(condition) assertThat(condition.isConditionSet).isTrue() assertThat(condition.isConditionMet).isFalse() flow.value = true + runCurrent() assertThat(condition.isConditionMet).isTrue() flow.value = false + runCurrent() assertThat(condition.isConditionMet).isFalse() - condition.testStop() + testStop(condition) } @Test fun stoppingConditionUnsubscribesFromFlow() = - testScope.runTest { + kosmos.runTest { val flow = MutableSharedFlow<Boolean>() - val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY) + val condition = flow.toCondition(scope = testScope, strategy = Condition.START_EAGERLY) assertThat(flow.subscriptionCount.value).isEqualTo(0) - condition.testStart() + testStart(condition) assertThat(flow.subscriptionCount.value).isEqualTo(1) - condition.testStop() + testStop(condition) assertThat(flow.subscriptionCount.value).isEqualTo(0) } - - fun Condition.testStart() { - addCallback(testCallback) - } - - fun Condition.testStop() { - removeCallback(testCallback) - } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java deleted file mode 100644 index 267f22bb2569..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java +++ /dev/null @@ -1,621 +0,0 @@ -/* - * 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.shared.condition; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.log.TableLogBufferBase; -import com.android.systemui.util.concurrency.FakeExecutor; -import com.android.systemui.util.time.FakeSystemClock; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class ConditionMonitorTest extends SysuiTestCase { - private FakeCondition mCondition1; - private FakeCondition mCondition2; - private FakeCondition mCondition3; - private HashSet<Condition> mConditions; - private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); - - @Mock - private CoroutineScope mScope; - @Mock - private TableLogBufferBase mLogBuffer; - - private Monitor mConditionMonitor; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - - mCondition1 = spy(new FakeCondition(mScope)); - mCondition2 = spy(new FakeCondition(mScope)); - mCondition3 = spy(new FakeCondition(mScope)); - mConditions = new HashSet<>(Arrays.asList(mCondition1, mCondition2, mCondition3)); - - mConditionMonitor = new Monitor(mExecutor); - } - - public Monitor.Subscription.Builder getDefaultBuilder( - Monitor.Callback callback) { - return new Monitor.Subscription.Builder(callback) - .addConditions(mConditions); - } - - private Condition createMockCondition() { - final Condition condition = Mockito.mock( - Condition.class); - when(condition.isConditionSet()).thenReturn(true); - return condition; - } - - @Test - public void testOverridingCondition() { - final Condition overridingCondition = createMockCondition(); - final Condition regularCondition = createMockCondition(); - final Monitor.Callback callback = Mockito.mock( - Monitor.Callback.class); - - final Monitor.Callback referenceCallback = Mockito.mock( - Monitor.Callback.class); - - final Monitor - monitor = new Monitor(mExecutor); - - monitor.addSubscription(getDefaultBuilder(callback) - .addCondition(overridingCondition) - .addCondition(regularCondition) - .build()); - - monitor.addSubscription(getDefaultBuilder(referenceCallback) - .addCondition(regularCondition) - .build()); - - mExecutor.runAllReady(); - - when(overridingCondition.isOverridingCondition()).thenReturn(true); - when(overridingCondition.isConditionMet()).thenReturn(true); - when(regularCondition.isConditionMet()).thenReturn(false); - - final ArgumentCaptor<Condition.Callback> mCallbackCaptor = - ArgumentCaptor.forClass(Condition.Callback.class); - - verify(overridingCondition).addCallback(mCallbackCaptor.capture()); - - mCallbackCaptor.getValue().onConditionChanged(overridingCondition); - mExecutor.runAllReady(); - - verify(callback).onConditionsChanged(eq(true)); - verify(referenceCallback).onConditionsChanged(eq(false)); - Mockito.clearInvocations(callback); - Mockito.clearInvocations(referenceCallback); - - when(regularCondition.isConditionMet()).thenReturn(true); - when(overridingCondition.isConditionMet()).thenReturn(false); - - mCallbackCaptor.getValue().onConditionChanged(overridingCondition); - mExecutor.runAllReady(); - - verify(callback).onConditionsChanged(eq(false)); - verify(referenceCallback, never()).onConditionsChanged(anyBoolean()); - } - - /** - * Ensures that when multiple overriding conditions are present, it is the aggregate of those - * conditions that are considered. - */ - @Test - public void testMultipleOverridingConditions() { - final Condition overridingCondition = createMockCondition(); - final Condition overridingCondition2 = createMockCondition(); - final Condition regularCondition = createMockCondition(); - final Monitor.Callback callback = Mockito.mock( - Monitor.Callback.class); - - final Monitor - monitor = new Monitor(mExecutor); - - monitor.addSubscription(getDefaultBuilder(callback) - .addCondition(overridingCondition) - .addCondition(overridingCondition2) - .build()); - - mExecutor.runAllReady(); - - when(overridingCondition.isOverridingCondition()).thenReturn(true); - when(overridingCondition.isConditionMet()).thenReturn(true); - when(overridingCondition2.isOverridingCondition()).thenReturn(true); - when(overridingCondition.isConditionMet()).thenReturn(false); - when(regularCondition.isConditionMet()).thenReturn(true); - - final ArgumentCaptor<Condition.Callback> mCallbackCaptor = - ArgumentCaptor.forClass(Condition.Callback.class); - - verify(overridingCondition).addCallback(mCallbackCaptor.capture()); - - mCallbackCaptor.getValue().onConditionChanged(overridingCondition); - mExecutor.runAllReady(); - - verify(callback).onConditionsChanged(eq(false)); - 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 = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build()); - mExecutor.runAllReady(); - mConditions.forEach(condition -> verify(condition).addCallback(any())); - - final Monitor.Callback callback2 = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback2).build()); - mExecutor.runAllReady(); - mConditions.forEach(condition -> verify(condition, times(1)).addCallback(any())); - } - - @Test - public void addCallback_addFirstCallback_reportWithDefaultValue() { - final Monitor.Callback callback = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback).build()); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - } - - @Test - public void addCallback_addSecondCallback_reportWithExistingValue() { - final Monitor.Callback callback1 = - mock(Monitor.Callback.class); - final Condition condition = mock( - Condition.class); - when(condition.isConditionMet()).thenReturn(true); - final Monitor - monitor = new Monitor(mExecutor); - monitor.addSubscription(new Monitor.Subscription.Builder(callback1) - .addCondition(condition) - .build()); - - final Monitor.Callback callback2 = - mock(Monitor.Callback.class); - monitor.addSubscription(new Monitor.Subscription.Builder(callback2) - .addCondition(condition) - .build()); - mExecutor.runAllReady(); - verify(callback2).onConditionsChanged(eq(true)); - } - - @Test - public void addCallback_noConditions_reportAllConditionsMet() { - final Monitor - monitor = new Monitor(mExecutor); - final Monitor.Callback callback = mock( - Monitor.Callback.class); - - monitor.addSubscription(new Monitor.Subscription.Builder(callback).build()); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - @Test - public void addCallback_preCondition_noConditions_reportAllConditionsMet() { - final Monitor - monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1))); - final Monitor.Callback callback = mock( - Monitor.Callback.class); - - monitor.addSubscription(new Monitor.Subscription.Builder(callback).build()); - mExecutor.runAllReady(); - verify(callback, never()).onConditionsChanged(true); - mCondition1.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - @Test - public void removeCallback_noFailureOnDoubleRemove() { - final Condition condition = mock( - Condition.class); - final Monitor - monitor = new Monitor(mExecutor); - final Monitor.Callback callback = - mock(Monitor.Callback.class); - final Monitor.Subscription.Token token = monitor.addSubscription( - new Monitor.Subscription.Builder(callback).addCondition(condition).build() - ); - monitor.removeSubscription(token); - mExecutor.runAllReady(); - // Ensure second removal doesn't cause an exception. - monitor.removeSubscription(token); - mExecutor.runAllReady(); - } - - @Test - public void removeCallback_shouldNoLongerReceiveUpdate() { - final Condition condition = mock( - Condition.class); - final Monitor - monitor = new Monitor(mExecutor); - final Monitor.Callback callback = - mock(Monitor.Callback.class); - final Monitor.Subscription.Token token = monitor.addSubscription( - new Monitor.Subscription.Builder(callback).addCondition(condition).build() - ); - monitor.removeSubscription(token); - mExecutor.runAllReady(); - clearInvocations(callback); - - final ArgumentCaptor<Condition.Callback> conditionCallbackCaptor = - ArgumentCaptor.forClass(Condition.Callback.class); - verify(condition).addCallback(conditionCallbackCaptor.capture()); - - final Condition.Callback conditionCallback = conditionCallbackCaptor.getValue(); - verify(condition).removeCallback(conditionCallback); - } - - @Test - public void removeCallback_removeLastCallback_removeCallbackFromAllConditions() { - final Monitor.Callback callback1 = - mock(Monitor.Callback.class); - final Monitor.Callback callback2 = - mock(Monitor.Callback.class); - final Monitor.Subscription.Token subscription1 = - mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build()); - final Monitor.Subscription.Token subscription2 = - mConditionMonitor.addSubscription(getDefaultBuilder(callback2).build()); - - mConditionMonitor.removeSubscription(subscription1); - mExecutor.runAllReady(); - mConditions.forEach(condition -> verify(condition, never()).removeCallback(any())); - - mConditionMonitor.removeSubscription(subscription2); - mExecutor.runAllReady(); - mConditions.forEach(condition -> verify(condition).removeCallback(any())); - } - - @Test - public void updateCallbacks_allConditionsMet_reportTrue() { - final Monitor.Callback callback = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback).build()); - clearInvocations(callback); - - mCondition1.fakeUpdateCondition(true); - mCondition2.fakeUpdateCondition(true); - mCondition3.fakeUpdateCondition(true); - mExecutor.runAllReady(); - - verify(callback).onConditionsChanged(true); - } - - @Test - public void updateCallbacks_oneConditionStoppedMeeting_reportFalse() { - final Monitor.Callback callback = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback).build()); - - mCondition1.fakeUpdateCondition(true); - mCondition2.fakeUpdateCondition(true); - mCondition3.fakeUpdateCondition(true); - clearInvocations(callback); - - mCondition1.fakeUpdateCondition(false); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - } - - @Test - public void updateCallbacks_shouldOnlyUpdateWhenValueChanges() { - final Monitor.Callback callback = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback).build()); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - clearInvocations(callback); - - mCondition1.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(callback, never()).onConditionsChanged(anyBoolean()); - - mCondition2.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(callback, never()).onConditionsChanged(anyBoolean()); - - mCondition3.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - @Test - public void clearCondition_shouldUpdateValue() { - mCondition1.fakeUpdateCondition(false); - mCondition2.fakeUpdateCondition(true); - mCondition3.fakeUpdateCondition(true); - - final Monitor.Callback callback = - mock(Monitor.Callback.class); - mConditionMonitor.addSubscription(getDefaultBuilder(callback).build()); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - - mCondition1.clearCondition(); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - @Test - public void unsetCondition_shouldNotAffectValue() { - final FakeCondition settableCondition = new FakeCondition(mScope, null, false); - mCondition1.fakeUpdateCondition(true); - mCondition2.fakeUpdateCondition(true); - mCondition3.fakeUpdateCondition(true); - - final Monitor.Callback callback = - mock(Monitor.Callback.class); - - mConditionMonitor.addSubscription(getDefaultBuilder(callback) - .addCondition(settableCondition) - .build()); - - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - @Test - public void setUnsetCondition_shouldAffectValue() { - final FakeCondition settableCondition = new FakeCondition(mScope, null, false); - mCondition1.fakeUpdateCondition(true); - mCondition2.fakeUpdateCondition(true); - mCondition3.fakeUpdateCondition(true); - - final Monitor.Callback callback = - mock(Monitor.Callback.class); - - mConditionMonitor.addSubscription(getDefaultBuilder(callback) - .addCondition(settableCondition) - .build()); - - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - clearInvocations(callback); - - settableCondition.fakeUpdateCondition(false); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - clearInvocations(callback); - - - settableCondition.clearCondition(); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - @Test - public void clearingOverridingCondition_shouldBeExcluded() { - final FakeCondition overridingCondition = new FakeCondition(mScope, true, true); - mCondition1.fakeUpdateCondition(false); - mCondition2.fakeUpdateCondition(false); - mCondition3.fakeUpdateCondition(false); - - final Monitor.Callback callback = - mock(Monitor.Callback.class); - - mConditionMonitor.addSubscription(getDefaultBuilder(callback) - .addCondition(overridingCondition) - .build()); - - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - clearInvocations(callback); - - overridingCondition.clearCondition(); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - } - - @Test - public void settingUnsetOverridingCondition_shouldBeIncluded() { - final FakeCondition overridingCondition = new FakeCondition(mScope, null, true); - mCondition1.fakeUpdateCondition(false); - mCondition2.fakeUpdateCondition(false); - mCondition3.fakeUpdateCondition(false); - - final Monitor.Callback callback = - mock(Monitor.Callback.class); - - mConditionMonitor.addSubscription(getDefaultBuilder(callback) - .addCondition(overridingCondition) - .build()); - - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(false); - clearInvocations(callback); - - overridingCondition.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(callback).onConditionsChanged(true); - } - - /** - * Ensures that the result of a condition being true leads to its nested condition being - * activated. - */ - @Test - public void testNestedCondition() { - mCondition1.fakeUpdateCondition(false); - final Monitor.Callback callback = - mock(Monitor.Callback.class); - - mCondition2.fakeUpdateCondition(false); - - // Create a nested condition - mConditionMonitor.addSubscription(new Monitor.Subscription.Builder( - new Monitor.Subscription.Builder(callback) - .addCondition(mCondition2) - .build()) - .addCondition(mCondition1) - .build()); - - mExecutor.runAllReady(); - - // Ensure the nested condition callback is not called at all. - verify(callback, never()).onActiveChanged(anyBoolean()); - verify(callback, never()).onConditionsChanged(anyBoolean()); - - // Update the inner condition to true and ensure that the nested condition is not triggered. - mCondition2.fakeUpdateCondition(true); - verify(callback, never()).onConditionsChanged(anyBoolean()); - mCondition2.fakeUpdateCondition(false); - - // Set outer condition and make sure the inner condition becomes active and reports that - // conditions aren't met - mCondition1.fakeUpdateCondition(true); - mExecutor.runAllReady(); - - verify(callback).onActiveChanged(eq(true)); - verify(callback).onConditionsChanged(eq(false)); - - Mockito.clearInvocations(callback); - - // Update the inner condition and make sure the callback is updated. - mCondition2.fakeUpdateCondition(true); - mExecutor.runAllReady(); - - verify(callback).onConditionsChanged(true); - - Mockito.clearInvocations(callback); - // Invalidate outer condition and make sure callback is informed, but the last state is - // not affected. - mCondition1.fakeUpdateCondition(false); - mExecutor.runAllReady(); - - verify(callback).onActiveChanged(eq(false)); - verify(callback, never()).onConditionsChanged(anyBoolean()); - } - - /** - * Ensure preconditions are applied to every subscription added to a monitor. - */ - @Test - public void testPreconditionMonitor() { - final Monitor.Callback callback = - mock(Monitor.Callback.class); - - mCondition2.fakeUpdateCondition(true); - final Monitor monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1))); - - monitor.addSubscription(new Monitor.Subscription.Builder(callback) - .addCondition(mCondition2) - .build()); - - mExecutor.runAllReady(); - - verify(callback, never()).onActiveChanged(anyBoolean()); - verify(callback, never()).onConditionsChanged(anyBoolean()); - - mCondition1.fakeUpdateCondition(true); - mExecutor.runAllReady(); - - verify(callback).onActiveChanged(eq(true)); - verify(callback).onConditionsChanged(eq(true)); - } - - @Test - public void testLoggingCallback() { - final Monitor monitor = new Monitor(mExecutor, Collections.emptySet(), mLogBuffer); - - final FakeCondition condition = new FakeCondition(mScope); - final FakeCondition overridingCondition = new FakeCondition( - mScope, - /* initialValue= */ false, - /* overriding= */ true); - - final Monitor.Callback callback = mock(Monitor.Callback.class); - monitor.addSubscription(getDefaultBuilder(callback) - .addCondition(condition) - .addCondition(overridingCondition) - .build()); - mExecutor.runAllReady(); - - // condition set to true - condition.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(mLogBuffer).logChange("", "FakeCondition", "True"); - - // condition set to false - condition.fakeUpdateCondition(false); - mExecutor.runAllReady(); - verify(mLogBuffer).logChange("", "FakeCondition", "False"); - - // condition unset - condition.fakeClearCondition(); - mExecutor.runAllReady(); - verify(mLogBuffer).logChange("", "FakeCondition", "Invalid"); - - // overriding condition set to true - overridingCondition.fakeUpdateCondition(true); - mExecutor.runAllReady(); - verify(mLogBuffer).logChange("", "FakeCondition[OVRD]", "True"); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.kt new file mode 100644 index 000000000000..dc45c5317b8e --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.kt @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2025 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.shared.condition + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.plugins.log.TableLogBufferBase +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock +import java.util.Arrays +import java.util.function.Consumer +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyBoolean +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +class ConditionMonitorTest : SysuiTestCase() { + private val kosmos = Kosmos() + + private lateinit var condition1: FakeCondition + private lateinit var condition2: FakeCondition + private lateinit var condition3: FakeCondition + private lateinit var conditions: HashSet<Condition> + private val executor = FakeExecutor(FakeSystemClock()) + + @Mock private lateinit var logBuffer: TableLogBufferBase + + private lateinit var conditionMonitor: Monitor + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + condition1 = Mockito.spy(FakeCondition(kosmos.testScope)) + condition2 = Mockito.spy(FakeCondition(kosmos.testScope)) + condition3 = Mockito.spy(FakeCondition(kosmos.testScope)) + conditions = HashSet(listOf(condition1, condition2, condition3)) + + conditionMonitor = Monitor(executor) + } + + fun getDefaultBuilder(callback: Monitor.Callback): Monitor.Subscription.Builder { + return Monitor.Subscription.Builder(callback).addConditions(conditions) + } + + private fun createMockCondition(): Condition { + val condition: Condition = mock() + whenever(condition.isConditionSet).thenReturn(true) + return condition + } + + @Test + fun testOverridingCondition() = + kosmos.runTest { + val overridingCondition = createMockCondition() + val regularCondition = createMockCondition() + val callback: Monitor.Callback = mock() + val referenceCallback: Monitor.Callback = mock() + + val monitor = Monitor(executor) + + monitor.addSubscription( + getDefaultBuilder(callback) + .addCondition(overridingCondition) + .addCondition(regularCondition) + .build() + ) + + monitor.addSubscription( + getDefaultBuilder(referenceCallback).addCondition(regularCondition).build() + ) + + executor.runAllReady() + + whenever(overridingCondition.isOverridingCondition).thenReturn(true) + whenever(overridingCondition.isConditionMet).thenReturn(true) + whenever(regularCondition.isConditionMet).thenReturn(false) + + val callbackCaptor = argumentCaptor<Condition.Callback>() + + Mockito.verify(overridingCondition).addCallback(callbackCaptor.capture()) + + callbackCaptor.lastValue.onConditionChanged(overridingCondition) + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(eq(true)) + Mockito.verify(referenceCallback).onConditionsChanged(eq(false)) + Mockito.clearInvocations(callback) + Mockito.clearInvocations(referenceCallback) + + whenever(regularCondition.isConditionMet).thenReturn(true) + whenever(overridingCondition.isConditionMet).thenReturn(false) + + callbackCaptor.lastValue.onConditionChanged(overridingCondition) + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(eq(false)) + Mockito.verify(referenceCallback, Mockito.never()).onConditionsChanged(anyBoolean()) + } + + /** + * Ensures that when multiple overriding conditions are present, it is the aggregate of those + * conditions that are considered. + */ + @Test + fun testMultipleOverridingConditions() = + kosmos.runTest { + val overridingCondition = createMockCondition() + val overridingCondition2 = createMockCondition() + val regularCondition = createMockCondition() + val callback: Monitor.Callback = mock() + + val monitor = Monitor(executor) + + monitor.addSubscription( + getDefaultBuilder(callback) + .addCondition(overridingCondition) + .addCondition(overridingCondition2) + .build() + ) + + executor.runAllReady() + + whenever(overridingCondition.isOverridingCondition).thenReturn(true) + whenever(overridingCondition.isConditionMet).thenReturn(true) + whenever(overridingCondition2.isOverridingCondition).thenReturn(true) + whenever(overridingCondition.isConditionMet).thenReturn(false) + whenever(regularCondition.isConditionMet).thenReturn(true) + + val mCallbackCaptor = argumentCaptor<Condition.Callback>() + + Mockito.verify(overridingCondition).addCallback(mCallbackCaptor.capture()) + + mCallbackCaptor.lastValue.onConditionChanged(overridingCondition) + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(eq(false)) + 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 + fun testUpdateRemovedCallback() = + kosmos.runTest { + val callback1: Monitor.Callback = mock() + val subscription1 = + conditionMonitor.addSubscription(getDefaultBuilder(callback1).build()) + val monitorCallback = argumentCaptor<Condition.Callback>() + executor.runAllReady() + Mockito.verify(condition1).addCallback(monitorCallback.capture()) + // This will execute first before the handler for onConditionChanged. + conditionMonitor.removeSubscription(subscription1) + monitorCallback.lastValue.onConditionChanged(condition1) + executor.runAllReady() + } + + @Test + fun addCallback_addFirstCallback_addCallbackToAllConditions() { + val callback1: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback1).build()) + executor.runAllReady() + conditions.forEach( + Consumer { condition: Condition -> Mockito.verify(condition).addCallback(any()) } + ) + + val callback2: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback2).build()) + executor.runAllReady() + conditions.forEach( + Consumer { condition: Condition -> + Mockito.verify(condition, Mockito.times(1)).addCallback(any()) + } + ) + } + + @Test + fun addCallback_addFirstCallback_reportWithDefaultValue() = + kosmos.runTest { + val callback: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback).build()) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + } + + @Test + fun addCallback_addSecondCallback_reportWithExistingValue() = + kosmos.runTest { + val callback1: Monitor.Callback = mock() + val condition: Condition = mock() + + whenever(condition.isConditionMet).thenReturn(true) + val monitor = Monitor(executor) + monitor.addSubscription( + Monitor.Subscription.Builder(callback1).addCondition(condition).build() + ) + + val callback2: Monitor.Callback = mock() + monitor.addSubscription( + Monitor.Subscription.Builder(callback2).addCondition(condition).build() + ) + executor.runAllReady() + Mockito.verify(callback2).onConditionsChanged(eq(true)) + } + + @Test + fun addCallback_noConditions_reportAllConditionsMet() = + kosmos.runTest { + val monitor = Monitor(executor) + val callback: Monitor.Callback = mock() + + monitor.addSubscription(Monitor.Subscription.Builder(callback).build()) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun addCallback_preCondition_noConditions_reportAllConditionsMet() = + kosmos.runTest { + val monitor = Monitor(executor, HashSet<Condition?>(Arrays.asList(condition1))) + val callback: Monitor.Callback = mock() + + monitor.addSubscription(Monitor.Subscription.Builder(callback).build()) + executor.runAllReady() + Mockito.verify(callback, Mockito.never()).onConditionsChanged(true) + condition1.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun removeCallback_noFailureOnDoubleRemove() = + kosmos.runTest { + val condition: Condition = mock() + val monitor = Monitor(executor) + val callback: Monitor.Callback = mock() + val token = + monitor.addSubscription( + Monitor.Subscription.Builder(callback).addCondition(condition).build() + ) + monitor.removeSubscription(token) + executor.runAllReady() + // Ensure second removal doesn't cause an exception. + monitor.removeSubscription(token) + executor.runAllReady() + } + + @Test + fun removeCallback_shouldNoLongerReceiveUpdate() = + kosmos.runTest { + val condition: Condition = mock() + val monitor = Monitor(executor) + val callback: Monitor.Callback = mock() + val token = + monitor.addSubscription( + Monitor.Subscription.Builder(callback).addCondition(condition).build() + ) + monitor.removeSubscription(token) + executor.runAllReady() + Mockito.clearInvocations(callback) + + val conditionCallbackCaptor = argumentCaptor<Condition.Callback>() + Mockito.verify(condition).addCallback(conditionCallbackCaptor.capture()) + + val conditionCallback = conditionCallbackCaptor.lastValue + Mockito.verify(condition).removeCallback(conditionCallback) + } + + @Test + fun removeCallback_removeLastCallback_removeCallbackFromAllConditions() = + kosmos.runTest { + val callback1: Monitor.Callback = mock() + val callback2: Monitor.Callback = mock() + val subscription1 = + conditionMonitor.addSubscription(getDefaultBuilder(callback1).build()) + val subscription2 = + conditionMonitor.addSubscription(getDefaultBuilder(callback2).build()) + + conditionMonitor.removeSubscription(subscription1) + executor.runAllReady() + conditions.forEach( + Consumer { condition: Condition -> + verify(condition, Mockito.never()).removeCallback(any()) + } + ) + + conditionMonitor.removeSubscription(subscription2) + executor.runAllReady() + conditions.forEach( + Consumer { condition: Condition -> Mockito.verify(condition).removeCallback(any()) } + ) + } + + @Test + fun updateCallbacks_allConditionsMet_reportTrue() = + kosmos.runTest { + val callback: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback).build()) + Mockito.clearInvocations(callback) + + condition1.fakeUpdateCondition(true) + condition2.fakeUpdateCondition(true) + condition3.fakeUpdateCondition(true) + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun updateCallbacks_oneConditionStoppedMeeting_reportFalse() = + kosmos.runTest { + val callback: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback).build()) + + condition1.fakeUpdateCondition(true) + condition2.fakeUpdateCondition(true) + condition3.fakeUpdateCondition(true) + Mockito.clearInvocations(callback) + + condition1.fakeUpdateCondition(false) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + } + + @Test + fun updateCallbacks_shouldOnlyUpdateWhenValueChanges() = + kosmos.runTest { + val callback: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback).build()) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + Mockito.clearInvocations(callback) + + condition1.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean()) + + condition2.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean()) + + condition3.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun clearCondition_shouldUpdateValue() = + kosmos.runTest { + condition1.fakeUpdateCondition(false) + condition2.fakeUpdateCondition(true) + condition3.fakeUpdateCondition(true) + + val callback: Monitor.Callback = mock() + conditionMonitor.addSubscription(getDefaultBuilder(callback).build()) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + + condition1.clearCondition() + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun unsetCondition_shouldNotAffectValue() = + kosmos.runTest { + val settableCondition = FakeCondition(testScope, null, false) + condition1.fakeUpdateCondition(true) + condition2.fakeUpdateCondition(true) + condition3.fakeUpdateCondition(true) + + val callback: Monitor.Callback = mock() + + conditionMonitor.addSubscription( + getDefaultBuilder(callback).addCondition(settableCondition).build() + ) + + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun setUnsetCondition_shouldAffectValue() = + kosmos.runTest { + val settableCondition = FakeCondition(testScope, null, false) + condition1.fakeUpdateCondition(true) + condition2.fakeUpdateCondition(true) + condition3.fakeUpdateCondition(true) + + val callback: Monitor.Callback = mock() + + conditionMonitor.addSubscription( + getDefaultBuilder(callback).addCondition(settableCondition).build() + ) + + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + Mockito.clearInvocations(callback) + + settableCondition.fakeUpdateCondition(false) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + Mockito.clearInvocations(callback) + + settableCondition.clearCondition() + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + @Test + fun clearingOverridingCondition_shouldBeExcluded() = + kosmos.runTest { + val overridingCondition = FakeCondition(testScope, true, true) + condition1.fakeUpdateCondition(false) + condition2.fakeUpdateCondition(false) + condition3.fakeUpdateCondition(false) + + val callback: Monitor.Callback = mock() + + conditionMonitor.addSubscription( + getDefaultBuilder(callback).addCondition(overridingCondition).build() + ) + + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + Mockito.clearInvocations(callback) + + overridingCondition.clearCondition() + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + } + + @Test + fun settingUnsetOverridingCondition_shouldBeIncluded() = + kosmos.runTest { + val overridingCondition = FakeCondition(testScope, null, true) + condition1.fakeUpdateCondition(false) + condition2.fakeUpdateCondition(false) + condition3.fakeUpdateCondition(false) + + val callback: Monitor.Callback = mock() + + conditionMonitor.addSubscription( + getDefaultBuilder(callback).addCondition(overridingCondition).build() + ) + + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(false) + Mockito.clearInvocations(callback) + + overridingCondition.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(callback).onConditionsChanged(true) + } + + /** + * Ensures that the result of a condition being true leads to its nested condition being + * activated. + */ + @Test + fun testNestedCondition() = + kosmos.runTest { + condition1.fakeUpdateCondition(false) + val callback: Monitor.Callback = mock() + + condition2.fakeUpdateCondition(false) + + // Create a nested condition + conditionMonitor.addSubscription( + Monitor.Subscription.Builder( + Monitor.Subscription.Builder(callback).addCondition(condition2).build() + ) + .addCondition(condition1) + .build() + ) + + executor.runAllReady() + + // Ensure the nested condition callback is not called at all. + Mockito.verify(callback, Mockito.never()).onActiveChanged(anyBoolean()) + Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean()) + + // Update the inner condition to true and ensure that the nested condition is not + // triggered. + condition2.fakeUpdateCondition(true) + Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean()) + condition2.fakeUpdateCondition(false) + + // Set outer condition and make sure the inner condition becomes active and reports that + // conditions aren't met + condition1.fakeUpdateCondition(true) + executor.runAllReady() + + Mockito.verify(callback).onActiveChanged(eq(true)) + Mockito.verify(callback).onConditionsChanged(eq(false)) + + Mockito.clearInvocations(callback) + + // Update the inner condition and make sure the callback is updated. + condition2.fakeUpdateCondition(true) + executor.runAllReady() + + Mockito.verify(callback).onConditionsChanged(true) + + Mockito.clearInvocations(callback) + // Invalidate outer condition and make sure callback is informed, but the last state is + // not affected. + condition1.fakeUpdateCondition(false) + executor.runAllReady() + + Mockito.verify(callback).onActiveChanged(eq(false)) + Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean()) + } + + /** Ensure preconditions are applied to every subscription added to a monitor. */ + @Test + fun testPreconditionMonitor() { + val callback: Monitor.Callback = mock() + + condition2.fakeUpdateCondition(true) + val monitor = Monitor(executor, HashSet<Condition?>(listOf(condition1))) + + monitor.addSubscription( + Monitor.Subscription.Builder(callback).addCondition(condition2).build() + ) + + executor.runAllReady() + + Mockito.verify(callback, Mockito.never()).onActiveChanged(anyBoolean()) + Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean()) + + condition1.fakeUpdateCondition(true) + executor.runAllReady() + + Mockito.verify(callback).onActiveChanged(eq(true)) + Mockito.verify(callback).onConditionsChanged(eq(true)) + } + + @Test + fun testLoggingCallback() = + kosmos.runTest { + val monitor = Monitor(executor, emptySet(), logBuffer) + + val condition = FakeCondition(testScope) + val overridingCondition = + FakeCondition(testScope, /* initialValue= */ false, /* overriding= */ true) + + val callback: Monitor.Callback = mock() + monitor.addSubscription( + getDefaultBuilder(callback) + .addCondition(condition) + .addCondition(overridingCondition) + .build() + ) + executor.runAllReady() + + // condition set to true + condition.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(logBuffer).logChange("", "FakeCondition", "True") + + // condition set to false + condition.fakeUpdateCondition(false) + executor.runAllReady() + Mockito.verify(logBuffer).logChange("", "FakeCondition", "False") + + // condition unset + condition.fakeClearCondition() + executor.runAllReady() + Mockito.verify(logBuffer).logChange("", "FakeCondition", "Invalid") + + // overriding condition set to true + overridingCondition.fakeUpdateCondition(true) + executor.runAllReady() + Mockito.verify(logBuffer).logChange("", "FakeCondition[OVRD]", "True") + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java deleted file mode 100644 index a224843e592a..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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.shared.condition; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class ConditionTest extends SysuiTestCase { - @Mock - CoroutineScope mScope; - - private FakeCondition mCondition; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mCondition = spy(new FakeCondition(mScope)); - } - - @Test - public void addCallback_addFirstCallback_triggerStart() { - final Condition.Callback callback = mock( - Condition.Callback.class); - mCondition.addCallback(callback); - verify(mCondition).start(); - } - - @Test - public void addCallback_addMultipleCallbacks_triggerStartOnlyOnce() { - final Condition.Callback callback1 = mock( - Condition.Callback.class); - final Condition.Callback callback2 = mock( - Condition.Callback.class); - final Condition.Callback callback3 = mock( - Condition.Callback.class); - - mCondition.addCallback(callback1); - mCondition.addCallback(callback2); - mCondition.addCallback(callback3); - - verify(mCondition, times(1)).start(); - } - - @Test - public void addCallback_alreadyStarted_triggerUpdate() { - final Condition.Callback callback1 = mock( - Condition.Callback.class); - mCondition.addCallback(callback1); - - mCondition.fakeUpdateCondition(true); - - final Condition.Callback callback2 = mock( - Condition.Callback.class); - mCondition.addCallback(callback2); - verify(callback2).onConditionChanged(mCondition); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void removeCallback_removeLastCallback_triggerStop() { - final Condition.Callback callback = mock( - Condition.Callback.class); - mCondition.addCallback(callback); - verify(mCondition, never()).stop(); - - mCondition.removeCallback(callback); - verify(mCondition).stop(); - } - - @Test - public void updateCondition_falseToTrue_reportTrue() { - mCondition.fakeUpdateCondition(false); - - final Condition.Callback callback = mock( - Condition.Callback.class); - mCondition.addCallback(callback); - - mCondition.fakeUpdateCondition(true); - verify(callback).onConditionChanged(eq(mCondition)); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void updateCondition_trueToFalse_reportFalse() { - mCondition.fakeUpdateCondition(true); - - final Condition.Callback callback = mock( - Condition.Callback.class); - mCondition.addCallback(callback); - - mCondition.fakeUpdateCondition(false); - verify(callback).onConditionChanged(eq(mCondition)); - assertThat(mCondition.isConditionMet()).isFalse(); - } - - @Test - public void updateCondition_trueToTrue_reportNothing() { - mCondition.fakeUpdateCondition(true); - - final Condition.Callback callback = mock( - Condition.Callback.class); - mCondition.addCallback(callback); - - mCondition.fakeUpdateCondition(true); - verify(callback, never()).onConditionChanged(eq(mCondition)); - } - - @Test - public void updateCondition_falseToFalse_reportNothing() { - mCondition.fakeUpdateCondition(false); - - final Condition.Callback callback = mock( - Condition.Callback.class); - mCondition.addCallback(callback); - - mCondition.fakeUpdateCondition(false); - verify(callback, never()).onConditionChanged(eq(mCondition)); - } - - @Test - public void clearCondition_reportsNotSet() { - mCondition.fakeUpdateCondition(false); - assertThat(mCondition.isConditionSet()).isTrue(); - mCondition.clearCondition(); - assertThat(mCondition.isConditionSet()).isFalse(); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.kt new file mode 100644 index 000000000000..f72185b72de6 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.kt @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2025 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.shared.condition + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.mockito.Mockito.mock +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock + +@SmallTest +@RunWith(AndroidJUnit4::class) +class ConditionTest : SysuiTestCase() { + private val kosmos = Kosmos() + private lateinit var underTest: FakeCondition + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + underTest = Mockito.spy(FakeCondition(kosmos.testScope)) + } + + @Test + fun addCallback_addFirstCallback_triggerStart() = + kosmos.runTest { + val callback = mock<Condition.Callback>() + underTest.addCallback(callback) + runCurrent() + Mockito.verify(underTest).start() + } + + @Test + fun addCallback_addMultipleCallbacks_triggerStartOnlyOnce() = + kosmos.runTest { + val callback1 = mock<Condition.Callback>() + val callback2 = mock<Condition.Callback>() + val callback3 = mock<Condition.Callback>() + + underTest.addCallback(callback1) + underTest.addCallback(callback2) + underTest.addCallback(callback3) + + runCurrent() + Mockito.verify(underTest).start() + } + + @Test + fun addCallback_alreadyStarted_triggerUpdate() = + kosmos.runTest { + val callback1 = mock<Condition.Callback>() + underTest.addCallback(callback1) + + underTest.fakeUpdateCondition(true) + + val callback2 = mock<Condition.Callback>() + underTest.addCallback(callback2) + Mockito.verify(callback2).onConditionChanged(underTest) + Truth.assertThat(underTest.isConditionMet).isTrue() + } + + @Test + fun removeCallback_removeLastCallback_triggerStop() = + kosmos.runTest { + val callback = mock<Condition.Callback>() + underTest.addCallback(callback) + Mockito.verify(underTest, Mockito.never()).stop() + + underTest.removeCallback(callback) + Mockito.verify(underTest).stop() + } + + @Test + fun updateCondition_falseToTrue_reportTrue() = + kosmos.runTest { + underTest.fakeUpdateCondition(false) + + val callback = mock<Condition.Callback>() + underTest.addCallback(callback) + + underTest.fakeUpdateCondition(true) + Mockito.verify(callback).onConditionChanged(eq(underTest)) + Truth.assertThat(underTest.isConditionMet).isTrue() + } + + @Test + fun updateCondition_trueToFalse_reportFalse() = + kosmos.runTest { + underTest.fakeUpdateCondition(true) + + val callback = mock<Condition.Callback>() + underTest.addCallback(callback) + + underTest.fakeUpdateCondition(false) + Mockito.verify(callback).onConditionChanged(eq(underTest)) + Truth.assertThat(underTest.isConditionMet).isFalse() + } + + @Test + fun updateCondition_trueToTrue_reportNothing() = + kosmos.runTest { + underTest.fakeUpdateCondition(true) + + val callback = mock<Condition.Callback>() + underTest.addCallback(callback) + + underTest.fakeUpdateCondition(true) + Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(underTest)) + } + + @Test + fun updateCondition_falseToFalse_reportNothing() = + kosmos.runTest { + underTest.fakeUpdateCondition(false) + + val callback = mock<Condition.Callback>() + underTest.addCallback(callback) + + underTest.fakeUpdateCondition(false) + Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(underTest)) + } + + @Test + fun clearCondition_reportsNotSet() = + kosmos.runTest { + underTest.fakeUpdateCondition(false) + Truth.assertThat(underTest.isConditionSet).isTrue() + underTest.clearCondition() + Truth.assertThat(underTest.isConditionSet).isFalse() + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java deleted file mode 100644 index da660e2f6009..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.shared.condition; - -import kotlinx.coroutines.CoroutineScope; - -/** - * Fake implementation of {@link Condition}, and provides a way for tests to update - * condition fulfillment. - */ -public class FakeCondition extends Condition { - FakeCondition(CoroutineScope scope) { - super(scope); - } - - FakeCondition(CoroutineScope scope, Boolean initialValue, boolean overriding) { - super(scope, initialValue, overriding); - } - - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } - - public void fakeUpdateCondition(boolean isConditionMet) { - updateCondition(isConditionMet); - } - - public void fakeClearCondition() { - clearCondition(); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.kt new file mode 100644 index 000000000000..340249c269b1 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2025 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.shared.condition + +import kotlinx.coroutines.CoroutineScope + +/** + * Fake implementation of [Condition], and provides a way for tests to update condition fulfillment. + */ +class FakeCondition : Condition { + constructor(scope: CoroutineScope) : super(scope) + + constructor( + scope: CoroutineScope, + initialValue: Boolean?, + overriding: Boolean, + ) : super(scope, initialValue, overriding) + + public override suspend fun start() {} + + public override fun stop() {} + + override val startStrategy: Int + get() = START_EAGERLY + + fun fakeUpdateCondition(isConditionMet: Boolean) { + updateCondition(isConditionMet) + } + + fun fakeClearCondition() { + clearCondition() + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java index 01046cd10d87..3c19179bc1c2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java @@ -227,7 +227,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { if (NotificationBundleUi.isEnabled()) { return row.getEntryAdapter().getSbn().getNotification(); } else { - return row.getEntry().getSbn().getNotification(); + return row.getEntryLegacy().getSbn().getNotification(); } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt index 03dee3aeb75c..72d21f1064af 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt @@ -24,13 +24,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.keyguardUpdateMonitor import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository +import com.android.systemui.testKosmos import com.android.systemui.tuner.TunerService import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.kotlin.JavaAdapter @@ -54,7 +54,7 @@ class OperatorNameViewControllerTest : SysuiTestCase() { private lateinit var underTest: OperatorNameViewController private lateinit var airplaneModeInteractor: AirplaneModeInteractor - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = TestScope() private val view = OperatorNameView(mContext) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt index 485b9febc284..8120c2d9f816 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt @@ -17,12 +17,17 @@ package com.android.systemui.statusbar.chips.call.ui.viewmodel import android.app.PendingIntent +import android.content.ComponentName +import android.content.Intent import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.activity.data.repository.activityManagerRepository +import com.android.systemui.activity.data.repository.fake +import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Icon @@ -51,6 +56,7 @@ import com.google.common.truth.Truth.assertThat import kotlin.test.Test import org.junit.runner.RunWith import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @@ -481,6 +487,303 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(pendingIntent, null) } + @Test + @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME) + @EnableChipsModernization + fun chipWithReturnAnimation_updatesCorrectly_withStateAndTransitionState() = + kosmos.runTest { + val pendingIntent = mock<PendingIntent>() + val intent = mock<Intent>() + whenever(pendingIntent.intent).thenReturn(intent) + val component = mock<ComponentName>() + whenever(intent.component).thenReturn(component) + + val expandable = mock<Expandable>() + val activityController = mock<ActivityTransitionAnimator.Controller>() + whenever( + expandable.activityTransitionController( + anyOrNull(), + anyOrNull(), + any(), + anyOrNull(), + any(), + ) + ) + .thenReturn(activityController) + + val latest by collectLastValue(underTest.chip) + + // Start off with no call. + removeOngoingCallState(key = NOTIFICATION_KEY) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java) + assertThat(latest!!.transitionManager!!.controllerFactory).isNull() + + // Call starts [NoCall -> InCall(isAppVisible=true), NoTransition]. + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue() + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + val factory = latest!!.transitionManager!!.controllerFactory + assertThat(factory!!.component).isEqualTo(component) + + // Request a return transition [InCall(isAppVisible=true), NoTransition -> + // ReturnRequested]. + factory.onCompose(expandable) + var controller = factory.createController(forLaunch = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isTrue() + + // Start the return transition [InCall(isAppVisible=true), ReturnRequested -> + // Returning]. + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // End the return transition [InCall(isAppVisible=true), Returning -> NoTransition]. + controller.onTransitionAnimationEnd(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // Settle the return transition [InCall(isAppVisible=true) -> + // InCall(isAppVisible=false), NoTransition]. + kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // Trigger a launch transition [InCall(isAppVisible=false) -> InCall(isAppVisible=true), + // NoTransition]. + kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, true) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // Request the return transition [InCall(isAppVisible=true), NoTransition -> + // LaunchRequested]. + controller = factory.createController(forLaunch = true) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // Start the return transition [InCall(isAppVisible=true), LaunchRequested -> + // Launching]. + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // End the return transition [InCall(isAppVisible=true), Launching -> NoTransition]. + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory) + assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse() + + // End the call with the app visible [InCall(isAppVisible=true) -> NoCall, + // NoTransition]. + removeOngoingCallState(key = NOTIFICATION_KEY) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java) + assertThat(latest!!.transitionManager!!.controllerFactory).isNull() + + // End the call with the app hidden [InCall(isAppVisible=false) -> NoCall, + // NoTransition]. + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + contentIntent = pendingIntent, + isAppVisible = false, + ) + removeOngoingCallState(key = NOTIFICATION_KEY) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java) + assertThat(latest!!.transitionManager!!.controllerFactory).isNull() + } + + @Test + @DisableFlags(StatusBarChipsReturnAnimations.FLAG_NAME) + fun chipLegacy_hasNoTransitionAnimationInformation() = + kosmos.runTest { + val latest by collectLastValue(underTest.chip) + + // NoCall + removeOngoingCallState(key = NOTIFICATION_KEY) + assertThat(latest!!.transitionManager).isNull() + + // InCall with visible app + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + assertThat(latest!!.transitionManager).isNull() + + // InCall with hidden app + kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, false) + assertThat(latest!!.transitionManager).isNull() + } + + @Test + @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME) + @EnableChipsModernization + fun chipWithReturnAnimation_chipDataChangesMidTransition() = + kosmos.runTest { + val pendingIntent = mock<PendingIntent>() + val intent = mock<Intent>() + whenever(pendingIntent.intent).thenReturn(intent) + val component = mock<ComponentName>() + whenever(intent.component).thenReturn(component) + + val expandable = mock<Expandable>() + val activityController = mock<ActivityTransitionAnimator.Controller>() + whenever( + expandable.activityTransitionController( + anyOrNull(), + anyOrNull(), + any(), + anyOrNull(), + any(), + ) + ) + .thenReturn(activityController) + + val latest by collectLastValue(underTest.chip) + + // Start with the app visible and trigger a return animation. + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + var factory = latest!!.transitionManager!!.controllerFactory!! + factory.onCompose(expandable) + var controller = factory.createController(forLaunch = false) + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + + // The chip changes state. + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 0, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + + // Reset the state and trigger a launch animation. + controller.onTransitionAnimationEnd(isExpandingFullyAbove = false) + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + factory = latest!!.transitionManager!!.controllerFactory!! + factory.onCompose(expandable) + controller = factory.createController(forLaunch = true) + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + + // The chip changes state. + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = -2, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + } + + @Test + @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME) + @EnableChipsModernization + fun chipWithReturnAnimation_chipDisappearsMidTransition() = + kosmos.runTest { + val pendingIntent = mock<PendingIntent>() + val intent = mock<Intent>() + whenever(pendingIntent.intent).thenReturn(intent) + val component = mock<ComponentName>() + whenever(intent.component).thenReturn(component) + + val expandable = mock<Expandable>() + val activityController = mock<ActivityTransitionAnimator.Controller>() + whenever( + expandable.activityTransitionController( + anyOrNull(), + anyOrNull(), + any(), + anyOrNull(), + any(), + ) + ) + .thenReturn(activityController) + + val latest by collectLastValue(underTest.chip) + + // Start with the app visible and trigger a return animation. + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + var factory = latest!!.transitionManager!!.controllerFactory!! + factory.onCompose(expandable) + var controller = factory.createController(forLaunch = false) + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + + // The chip disappears. + removeOngoingCallState(key = NOTIFICATION_KEY) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java) + + // Reset the state and trigger a launch animation. + controller.onTransitionAnimationEnd(isExpandingFullyAbove = false) + addOngoingCallState( + key = NOTIFICATION_KEY, + startTimeMs = 345, + contentIntent = pendingIntent, + uid = NOTIFICATION_UID, + isAppVisible = true, + ) + factory = latest!!.transitionManager!!.controllerFactory!! + factory.onCompose(expandable) + controller = factory.createController(forLaunch = true) + controller.onTransitionAnimationStart(isExpandingFullyAbove = false) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java) + assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse() + + // The chip disappears. + removeOngoingCallState(key = NOTIFICATION_KEY) + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java) + } + companion object { fun createStatusBarIconViewOrNull(): StatusBarIconView? = if (StatusBarConnectedDisplays.isEnabled) { @@ -500,6 +803,8 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { } .build() + private const val NOTIFICATION_KEY = "testKey" + private const val NOTIFICATION_UID = 12345 private const val PROMOTED_BACKGROUND_COLOR = 65 private const val PROMOTED_PRIMARY_TEXT_COLOR = 98 diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt index b2174c1b1d8c..21a4560dafee 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt @@ -20,12 +20,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel import com.android.systemui.statusbar.policy.CastDevice +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runCurrent @@ -35,7 +35,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class MediaRouterChipInteractorTest : SysuiTestCase() { - val kosmos = Kosmos() + val kosmos = testKosmos() val testScope = kosmos.testScope val mediaRouterRepository = kosmos.fakeMediaRouterRepository diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt index 274efbb50788..568129706458 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt @@ -30,7 +30,6 @@ import android.view.Window import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.mediaprojection.data.model.MediaProjectionState @@ -41,6 +40,7 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.me import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runCurrent @@ -57,7 +57,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class EndCastScreenToOtherDeviceDialogDelegateTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val sysuiDialog = mock<SystemUIDialog>() private lateinit var underTest: EndCastScreenToOtherDeviceDialogDelegate diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt index 88207d1c61d8..30a415cb9906 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt @@ -26,7 +26,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository @@ -35,6 +34,7 @@ import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor. import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.policy.CastDevice +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runCurrent @@ -51,7 +51,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class EndGenericCastToOtherDeviceDialogDelegateTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val sysuiDialog = mock<SystemUIDialog>() private lateinit var underTest: EndGenericCastToOtherDeviceDialogDelegate diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt index ccc844ad5837..d921ab3b284d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt @@ -30,7 +30,6 @@ import com.android.systemui.animation.mockDialogTransitionAnimator import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.mediaprojection.data.model.MediaProjectionState @@ -52,6 +51,7 @@ import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory import com.android.systemui.statusbar.phone.ongoingcall.DisableChipsModernization import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization import com.android.systemui.statusbar.policy.CastDevice +import com.android.systemui.testKosmos import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlin.test.Test @@ -69,7 +69,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val testScope = kosmos.testScope private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository private val mediaRouterRepo = kosmos.fakeMediaRouterRepository diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt index 795988f0087f..fac50b38d838 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt @@ -24,12 +24,12 @@ import android.content.pm.PackageManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.mediaprojection.data.model.MediaProjectionState import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import org.junit.runner.RunWith @@ -42,7 +42,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class EndMediaProjectionDialogHelperTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val underTest = kosmos.endMediaProjectionDialogHelper diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt index f560ee7730ae..981c9525f636 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt @@ -30,7 +30,6 @@ import android.view.Window import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask @@ -39,6 +38,7 @@ import com.android.systemui.screenrecord.data.repository.screenRecordRepository import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.screenRecordChipInteractor import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runCurrent @@ -55,7 +55,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class EndScreenRecordingDialogDelegateTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val sysuiDialog = mock<SystemUIDialog>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt index 95aa6cd3250b..b2e90ecbeef1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt @@ -30,7 +30,6 @@ import android.view.Window import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.mediaprojection.data.model.MediaProjectionState @@ -41,6 +40,7 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.me import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.test.runCurrent @@ -57,7 +57,7 @@ import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class EndShareScreenToAppDialogDelegateTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private val sysuiDialog = mock<SystemUIDialog>() private lateinit var underTest: EndShareScreenToAppDialogDelegate diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt index e3a84fd2c2eb..6d91fb5a10cb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt @@ -22,12 +22,12 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlin.test.Test import kotlinx.coroutines.flow.MutableStateFlow @@ -39,7 +39,7 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class ChipTransitionHelperTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = kosmos.testScope @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt index 2f6bedb42e45..ea61b715475d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt @@ -29,7 +29,6 @@ import com.android.internal.statusbar.LetterboxDetails import com.android.internal.view.AppearanceRegion import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.data.model.StatusBarMode import com.android.systemui.statusbar.layout.BoundsPair @@ -42,6 +41,7 @@ import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.capture @@ -59,7 +59,7 @@ import org.mockito.Mockito.verify @SmallTest @RunWith(AndroidJUnit4::class) class StatusBarModeRepositoryImplTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope = TestScope() private val commandQueue = mock<CommandQueue>() private val letterboxAppearanceCalculator = mock<LetterboxAppearanceCalculator>() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt index a13b8647e170..9faab58913f0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt @@ -24,6 +24,7 @@ import android.testing.TestableLooper.RunWithLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import com.android.systemui.statusbar.notification.shared.NotificationBundleUi import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -152,4 +153,10 @@ class BundleEntryAdapterTest : SysuiTestCase() { fun canShowFullScreen() { assertThat(underTest.isFullScreenCapable()).isFalse() } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getPeopleNotificationType() { + assertThat(underTest.getPeopleNotificationType()).isEqualTo(TYPE_NON_PERSON) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt index faafa073be4c..12ade62c3570 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt @@ -30,6 +30,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.res.R import com.android.systemui.statusbar.RankingBuilder import com.android.systemui.statusbar.notification.mockNotificationActivityStarter +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.entryAdapterFactory import com.android.systemui.statusbar.notification.row.mockNotificationActionClickManager @@ -41,6 +42,7 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito +import org.mockito.Mockito.mock import org.mockito.Mockito.verify @SmallTest @@ -334,6 +336,16 @@ class NotificationEntryAdapterTest : SysuiTestCase() { @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getPeopleNotificationType() { + val entry = kosmos.msgStyleBubbleableFullPerson + + underTest = factory.create(entry) as NotificationEntryAdapter + + assertThat(underTest.peopleNotificationType).isEqualTo(TYPE_FULL_PERSON) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) fun canShowFullScreen() { val notification: Notification = Notification.Builder(mContext, "") @@ -353,6 +365,22 @@ class NotificationEntryAdapterTest : SysuiTestCase() { @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun onDragSuccess() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .addAction(mock(Notification.Action::class.java)) + .build() + val entry = NotificationEntryBuilder().setNotification(notification).build() + + underTest = factory.create(entry) as NotificationEntryAdapter + + underTest.onDragSuccess() + verify(kosmos.mockNotificationActivityStarter).onDragSuccess(entry) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) fun onNotificationBubbleIconClicked() { val notification: Notification = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() @@ -380,4 +408,36 @@ class NotificationEntryAdapterTest : SysuiTestCase() { underTest.onNotificationActionClicked() verify(kosmos.mockNotificationActionClickManager).onNotificationActionClicked(entry) } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getDismissState() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + entry.dismissState = NotificationEntry.DismissState.PARENT_DISMISSED + + underTest = factory.create(entry) as NotificationEntryAdapter + + assertThat(underTest.dismissState).isEqualTo(entry.dismissState) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun onEntryClicked() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .addAction(mock(Notification.Action::class.java)) + .build() + val entry = NotificationEntryBuilder().setNotification(notification).build() + val row = mock(ExpandableNotificationRow::class.java) + + underTest = factory.create(entry) as NotificationEntryAdapter + + + underTest.onEntryClicked(row) + verify(kosmos.mockNotificationActivityStarter).onNotificationClicked(entry, row) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 790b2c343a11..bfd700dcc302 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -58,6 +58,7 @@ import com.android.systemui.res.R; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips; +import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi; import com.android.systemui.util.time.FakeSystemClock; @@ -151,7 +152,8 @@ public class NotificationEntryTest extends SysuiTestCase { .build(); NotificationEntry entry = - new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + new NotificationEntry(sbn, ranking, + UseElapsedRealtimeForCreationTime.getCurrentTime(mClock)); assertFalse(entry.isBlockable()); } @@ -251,7 +253,8 @@ public class NotificationEntryTest extends SysuiTestCase { .build(); NotificationEntry entry = - new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + new NotificationEntry(sbn, ranking, + UseElapsedRealtimeForCreationTime.getCurrentTime(mClock)); assertEquals(systemGeneratedSmartActions, entry.getSmartActions()); assertEquals(NOTIFICATION_CHANNEL, entry.getChannel()); @@ -365,7 +368,8 @@ public class NotificationEntryTest extends SysuiTestCase { .setKey(sbn.getKey()) .build(); NotificationEntry entry = - new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + new NotificationEntry(sbn, ranking, + UseElapsedRealtimeForCreationTime.getCurrentTime(mClock)); assertFalse(entry.isChannelVisibilityPrivate()); } @@ -378,7 +382,8 @@ public class NotificationEntryTest extends SysuiTestCase { .setKey(sbn.getKey()) .build(); NotificationEntry entry = - new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + new NotificationEntry(sbn, ranking, + UseElapsedRealtimeForCreationTime.getCurrentTime(mClock)); assertFalse(entry.isChannelVisibilityPrivate()); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt index 7fa157fa7cb3..ba2d40ba6a0d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt @@ -27,7 +27,6 @@ import android.testing.TestableLooper.RunWithLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest @@ -35,10 +34,10 @@ import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.core.StatusBarRootModernization -import com.android.systemui.statusbar.notification.buildNotificationEntry -import com.android.systemui.statusbar.notification.buildOngoingCallEntry -import com.android.systemui.statusbar.notification.buildPromotedOngoingEntry import com.android.systemui.statusbar.notification.collection.buildEntry +import com.android.systemui.statusbar.notification.collection.buildNotificationEntry +import com.android.systemui.statusbar.notification.collection.buildOngoingCallEntry +import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner import com.android.systemui.statusbar.notification.collection.notifPipeline @@ -49,7 +48,6 @@ import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernizat import com.android.systemui.testKosmos import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat -import kotlinx.coroutines.test.runTest import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt index ef0a4169d98e..d532010f4c55 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt @@ -50,6 +50,7 @@ import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable.PluggableListener import com.android.systemui.statusbar.notification.collection.notifPipeline @@ -323,7 +324,10 @@ class VisualStabilityCoordinatorTest(flags: FlagsParameterization) : SysuiTestCa setPulsing(true) // WHEN we temporarily allow section changes for this notification entry - underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis()) + underTest.temporarilyAllowSectionChanges( + entry, + UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock), + ) // THEN group changes aren't allowed assertThat(notifStabilityManager.isGroupChangeAllowed(entry)).isFalse() @@ -349,7 +353,10 @@ class VisualStabilityCoordinatorTest(flags: FlagsParameterization) : SysuiTestCa setPulsing(false) // WHEN we temporarily allow section changes for this notification entry - underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.uptimeMillis()) + underTest.temporarilyAllowSectionChanges( + entry, + UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock), + ) // THEN the notification list is invalidated verifyStabilityManagerWasInvalidated(times(1)) @@ -365,7 +372,10 @@ class VisualStabilityCoordinatorTest(flags: FlagsParameterization) : SysuiTestCa setPulsing(false) // WHEN we temporarily allow section changes for this notification entry - underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis()) + underTest.temporarilyAllowSectionChanges( + entry, + UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock), + ) // THEN invalidate is not called because this entry was never suppressed from reordering verifyStabilityManagerWasInvalidated(never()) @@ -382,7 +392,10 @@ class VisualStabilityCoordinatorTest(flags: FlagsParameterization) : SysuiTestCa assertThat(notifStabilityManager.isSectionChangeAllowed(entry)).isTrue() // WHEN we temporarily allow section changes for this notification entry - underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis()) + underTest.temporarilyAllowSectionChanges( + entry, + UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock), + ) // THEN invalidate is not called because this entry was never suppressed from // reordering; @@ -415,7 +428,10 @@ class VisualStabilityCoordinatorTest(flags: FlagsParameterization) : SysuiTestCa setPulsing(true) // WHEN we temporarily allow section changes for this notification entry - underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis()) + underTest.temporarilyAllowSectionChanges( + entry, + UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock), + ) // can now reorder, so invalidates verifyStabilityManagerWasInvalidated(times(1)) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt index 6926677feda0..6192399c522b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt @@ -28,9 +28,9 @@ import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.core.StatusBarRootModernization -import com.android.systemui.statusbar.notification.buildNotificationEntry -import com.android.systemui.statusbar.notification.buildOngoingCallEntry -import com.android.systemui.statusbar.notification.buildPromotedOngoingEntry +import com.android.systemui.statusbar.notification.collection.buildNotificationEntry +import com.android.systemui.statusbar.notification.collection.buildOngoingCallEntry +import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt index bb12eff51288..d306a5bea433 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt @@ -58,11 +58,13 @@ import com.android.systemui.statusbar.notification.stack.ui.view.NotificationRow import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.SmartReplyConstants import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.time.SystemClock +import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor import com.google.android.msdl.domain.MSDLPlayer import junit.framework.Assert import org.junit.After @@ -84,6 +86,8 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() { private val appName = "MyApp" private val notifKey = "MyNotifKey" + private val kosmos = testKosmos() + private val view: ExpandableNotificationRow = mock() private val activableNotificationViewController: ActivatableNotificationViewController = mock() private val rivSubComponentFactory: RemoteInputViewSubcomponent.Factory = mock() @@ -160,6 +164,7 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() { msdlPlayer, rebindingTracker, entryAdapterFactory, + kosmos.windowRootViewBlurInteractor, ) whenever(view.childrenContainer).thenReturn(childrenContainer) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt index b5f3269903b8..0ac5fe95957c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt @@ -58,7 +58,6 @@ import com.android.internal.logging.metricsLogger import com.android.internal.logging.uiEventLoggerFake import com.android.systemui.Dependency import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.res.R import com.android.systemui.statusbar.RankingBuilder @@ -70,6 +69,7 @@ import com.android.systemui.statusbar.notification.row.icon.AppIconProvider import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider import com.android.systemui.statusbar.notification.row.icon.appIconProvider import com.android.systemui.statusbar.notification.row.icon.notificationIconStyleProvider +import com.android.systemui.testKosmos import com.android.telecom.telecomManager import com.google.common.truth.Truth.assertThat import java.util.concurrent.CountDownLatch @@ -91,7 +91,7 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) @RunWithLooper class NotificationInfoTest : SysuiTestCase() { - private val kosmos = Kosmos().also { it.testCase = this } + private val kosmos = testKosmos().also { it.testCase = this } private lateinit var underTest: NotificationInfo private lateinit var notificationChannel: NotificationChannel diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java index 9fdfca14a5b2..ce120c51db6a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java @@ -38,7 +38,9 @@ import android.view.ViewGroup; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; +import com.android.systemui.statusbar.notification.collection.EntryAdapter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; @@ -54,6 +56,7 @@ import org.mockito.Mockito; @SmallTest public class NotificationMenuRowTest extends LeakCheckedTest { + private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); private ExpandableNotificationRow mRow; private View mView; private PeopleNotificationIdentifier mPeopleNotificationIdentifier; @@ -66,6 +69,8 @@ public class NotificationMenuRowTest extends LeakCheckedTest { mPeopleNotificationIdentifier = mock(PeopleNotificationIdentifier.class); NotificationEntry entry = new NotificationEntryBuilder().build(); when(mRow.getEntry()).thenReturn(entry); + EntryAdapter entryAdapter = mKosmos.getEntryAdapterFactory().create(entry); + when(mRow.getEntryAdapter()).thenReturn(entryAdapter); } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java index af67a04d2f2a..2d4063b2f667 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java @@ -27,7 +27,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import android.platform.test.annotations.EnableFlags; import android.provider.Settings; import android.testing.TestableResources; import android.view.View; @@ -39,7 +38,6 @@ import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.AnimatorTestRule; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; @@ -93,7 +91,6 @@ public class NotificationSnoozeTest extends SysuiTestCase { } @Test - @EnableFlags(Flags.FLAG_NOTIFICATION_UNDO_GUTS_ON_CONFIG_CHANGED) public void closeControls_withoutSave_performsUndo() { ArrayList<SnoozeOption> options = mUnderTest.getDefaultSnoozeOptions(); mUnderTest.mSelectedOption = options.getFirst(); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt index 3d1fdee306f4..961616c99cb1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt @@ -22,8 +22,6 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.accessibility.data.repository.FakeAccessibilityRepository import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.testKosmos -import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -34,16 +32,12 @@ import org.junit.runner.RunWith @SmallTest class ActivatableNotificationViewModelTest : SysuiTestCase() { - private val kosmos = testKosmos() - // fakes private val a11yRepo = FakeAccessibilityRepository() // real impls private val a11yInteractor = AccessibilityInteractor(a11yRepo) - private val windowRootViewBlurInteractor = kosmos.windowRootViewBlurInteractor - private val underTest = ActivatableNotificationViewModel(a11yInteractor, - windowRootViewBlurInteractor) + private val underTest = ActivatableNotificationViewModel(a11yInteractor) @Test fun isTouchable_whenA11yTouchExplorationDisabled() = runTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt index 048028cdc0fa..db0c59f6d602 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt @@ -23,12 +23,12 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testCase import com.android.systemui.plugins.statusbar.statusBarStateController import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.statusbar.lockscreenShadeTransitionController import com.android.systemui.statusbar.phone.screenOffAnimationController +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test @@ -44,7 +44,7 @@ import org.mockito.kotlin.whenever class NotificationShelfInteractorTest : SysuiTestCase() { private val kosmos = - Kosmos().apply { + testKosmos().apply { testCase = this@NotificationShelfInteractorTest lockscreenShadeTransitionController = mock() screenOffAnimationController = mock() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt index 6381b4e0fef7..7265262183ca 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt @@ -24,7 +24,6 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testCase @@ -35,6 +34,7 @@ import com.android.systemui.shade.domain.interactor.enableSingleShade import com.android.systemui.shade.domain.interactor.enableSplitShade import com.android.systemui.statusbar.lockscreenShadeTransitionController import com.android.systemui.statusbar.phone.screenOffAnimationController +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test @@ -50,7 +50,7 @@ import org.mockito.kotlin.whenever class NotificationShelfViewModelTest : SysuiTestCase() { private val kosmos = - Kosmos().apply { + testKosmos().apply { testCase = this@NotificationShelfViewModelTest lockscreenShadeTransitionController = mock() screenOffAnimationController = mock() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt index 13da04e8c7cc..378ffb525554 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt @@ -16,16 +16,22 @@ package com.android.systemui.statusbar.notification.stack +import android.app.Notification +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.flags.andSceneContainer +import com.android.systemui.res.R import com.android.systemui.shade.transition.LargeScreenShadeInterpolator import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository import com.android.systemui.statusbar.notification.headsup.AvalancheController +import com.android.systemui.statusbar.notification.shared.NotificationBundleUi import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -33,6 +39,7 @@ import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyString import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @@ -389,6 +396,36 @@ class AmbientStateTest(flags: FlagsParameterization) : SysuiTestCase() { assertThat(sut.isClosing).isFalse() } // endregion + + // region isPulsing + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isPulsing_key() { + whenever(headsupRepository.isHeadsUpEntry(anyString())).thenReturn(true); + sut.isPulsing = true + assertThat(sut.isPulsing("key")).isTrue() + + whenever(headsupRepository.isHeadsUpEntry(anyString())).thenReturn(false); + sut.isPulsing = true + assertThat(sut.isPulsing("key")).isFalse() + } + + @Test + @DisableFlags(NotificationBundleUi.FLAG_NAME) + fun isPulsing_entry() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + val entry = NotificationEntryBuilder().setNotification(notification).build() + + sut.isPulsing = true + entry.setIsHeadsUpEntry(true) + assertThat(sut.isPulsing(entry)).isTrue() + + sut.isPulsing = true + entry.setIsHeadsUpEntry(false) + assertThat(sut.isPulsing(entry)).isFalse() + } + // endregion } // region Arrange helper methods. diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt index 46430afecbb1..1f37291efbab 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt @@ -790,6 +790,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() { } @Test + @DisableFlags(Flags.FLAG_GLANCEABLE_HUB_V2) fun animateToGlanceableHub_affectsAlpha() = testScope.runTest { try { @@ -809,6 +810,7 @@ class KeyguardStatusBarViewControllerTest : SysuiTestCase() { } @Test + @DisableFlags(Flags.FLAG_GLANCEABLE_HUB_V2) fun animateToGlanceableHub_alphaResetOnCommunalNotShowing() = testScope.runTest { try { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java index c5abd026b369..19e98387a120 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java @@ -106,6 +106,7 @@ public final class NotificationGroupTestHelper { ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); entry.setRow(row); when(row.getEntry()).thenReturn(entry); + when(row.getEntryLegacy()).thenReturn(entry); return entry; } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index eb95ddb39b40..c58b4bc9953c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -30,7 +30,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.concurrency.fakeExecutor import com.android.systemui.dump.DumpManager -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer import com.android.systemui.res.R @@ -48,6 +47,7 @@ import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingC import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.statusbar.window.StatusBarWindowControllerStore +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -70,7 +70,7 @@ import org.mockito.kotlin.whenever @TestableLooper.RunWithLooper @DisableFlags(StatusBarChipsModernization.FLAG_NAME) class OngoingCallControllerTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val mainExecutor = kosmos.fakeExecutor private val testScope = kosmos.testScope diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt index a44631348796..7de56ddc06c3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt @@ -19,12 +19,11 @@ package com.android.systemui.statusbar.phone.ongoingcall.data.repository import android.platform.test.annotations.DisableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION import com.android.systemui.SysuiTestCase -import com.android.systemui.kosmos.Kosmos import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @@ -33,7 +32,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) @DisableFlags(StatusBarChipsModernization.FLAG_NAME) class OngoingCallRepositoryTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val underTest = kosmos.ongoingCallRepository @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt index f4204af7829b..84f1d5cd4895 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt @@ -23,7 +23,6 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.activity.data.repository.activityManagerRepository import com.android.systemui.activity.data.repository.fake import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher @@ -36,6 +35,7 @@ import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCall import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.removeOngoingCallState import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before @@ -51,7 +51,7 @@ import org.mockito.kotlin.verify @RunWith(AndroidJUnit4::class) @EnableChipsModernization class OngoingCallInteractorTest : SysuiTestCase() { - private val kosmos = Kosmos().useUnconfinedTestDispatcher() + private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val underTest = kosmos.ongoingCallInteractor @Before diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt index 91b3896332f5..39cf02dbc772 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt @@ -54,9 +54,7 @@ class FakeHomeStatusBarViewModel( MutableStateFlow(OngoingActivityChipModel.Inactive()) override val ongoingActivityChips = - MutableStateFlow( - ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false) - ) + ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false) override val ongoingActivityChipsLegacy = MutableStateFlow(MultipleOngoingActivityChipsModelLegacy()) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt index 2da692b4cb45..20cf3ae6b8dd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt @@ -49,6 +49,7 @@ import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher +import com.android.systemui.lifecycle.activateIn import com.android.systemui.log.assertLogsWtf import com.android.systemui.mediaprojection.data.model.MediaProjectionState import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository @@ -107,7 +108,8 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class HomeStatusBarViewModelImplTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() - private val Kosmos.underTest by Kosmos.Fixture { kosmos.homeStatusBarViewModel } + private val Kosmos.underTest by + Kosmos.Fixture { kosmos.homeStatusBarViewModel.also { it.activateIn(kosmos.testScope) } } @Before fun setUp() { @@ -891,32 +893,26 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @EnableChipsModernization fun ongoingActivityChips_statusBarHidden_noSecureCamera_noHun_notAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - // home status bar not allowed kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen) kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null) - assertThat(latest!!.areChipsAllowed).isFalse() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isFalse() } @Test @EnableChipsModernization fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_noHun_isAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - transitionKeyguardToGone() - assertThat(latest!!.areChipsAllowed).isTrue() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue() } @Test @EnableChipsModernization fun ongoingActivityChips_statusBarNotHidden_secureCamera_noHun_notAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - fakeKeyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.OCCLUDED, @@ -924,7 +920,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { ) kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) - assertThat(latest!!.areChipsAllowed).isFalse() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isFalse() } @Test @@ -932,8 +928,6 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @EnableChipsModernization fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_notAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - transitionKeyguardToGone() headsUpNotificationRepository.setNotifications( @@ -943,7 +937,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { ) ) - assertThat(latest!!.areChipsAllowed).isFalse() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isFalse() } @Test @@ -951,8 +945,6 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @EnableChipsModernization fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_isAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - transitionKeyguardToGone() headsUpNotificationRepository.setNotifications( @@ -962,16 +954,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { ) ) - assertThat(latest!!.areChipsAllowed).isTrue() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue() } @Test @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) @EnableChipsModernization - fun ongoingActivityChips_tatusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() = + fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - transitionKeyguardToGone() headsUpNotificationRepository.setNotifications( @@ -981,7 +971,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { ) ) - assertThat(latest!!.areChipsAllowed).isTrue() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue() } @Test @@ -989,8 +979,6 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @EnableChipsModernization fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_isAllowed() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) - transitionKeyguardToGone() headsUpNotificationRepository.setNotifications( @@ -1000,7 +988,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { ) ) - assertThat(latest!!.areChipsAllowed).isTrue() + assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue() } @Test @@ -1008,17 +996,16 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @EnableChipsModernization fun ongoingActivityChips_followsChipsViewModel() = kosmos.runTest { - val latest by collectLastValue(underTest.ongoingActivityChips) transitionKeyguardToGone() screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording - assertIsScreenRecordChip(latest!!.chips.active[0]) + assertIsScreenRecordChip(underTest.ongoingActivityChips.chips.active[0]) addOngoingCallState(key = "call") - assertIsScreenRecordChip(latest!!.chips.active[0]) - assertIsCallChip(latest!!.chips.active[1], "call", context) + assertIsScreenRecordChip(underTest.ongoingActivityChips.chips.active[0]) + assertIsCallChip(underTest.ongoingActivityChips.chips.active[1], "call", context) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt index 92bec70d2c4d..18a124cf362e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt @@ -38,7 +38,6 @@ import com.android.systemui.display.data.repository.DeviceStateRepository.Device import com.android.systemui.display.data.repository.fakeDeviceStateRepository import com.android.systemui.foldedDeviceStateList import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor -import com.android.systemui.kosmos.Kosmos import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setScreenPowerState @@ -47,6 +46,7 @@ import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_OFF import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_ON import com.android.systemui.shared.system.SysUiStatsLog import com.android.systemui.statusbar.policy.FakeConfigurationController +import com.android.systemui.testKosmos import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.COOL_DOWN_DURATION import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.FOLDABLE_DEVICE_STATE_CLOSED import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.FOLDABLE_DEVICE_STATE_HALF_OPEN @@ -89,7 +89,7 @@ class DisplaySwitchLatencyTrackerTest : SysuiTestCase() { private lateinit var displaySwitchLatencyTracker: DisplaySwitchLatencyTracker @Captor private lateinit var loggerArgumentCaptor: ArgumentCaptor<DisplaySwitchLatencyEvent> - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val mockContext = mock<Context>() private val resources = mock<Resources>() private val foldStateRepository = kosmos.fakeDeviceStateRepository diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt index dfc4d0f07df8..98d99f781879 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt @@ -28,7 +28,6 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.animation.AnimatorTestRule import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState import com.android.systemui.display.data.repository.fakeDeviceStateRepository -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest @@ -36,6 +35,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.power.shared.model.ScreenPowerState import com.android.systemui.statusbar.LightRevealScrim +import com.android.systemui.testKosmos import com.android.systemui.util.animation.data.repository.fakeAnimationStatusRepository import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy @@ -61,7 +61,7 @@ import org.mockito.kotlin.whenever class FoldLightRevealOverlayAnimationTest : SysuiTestCase() { @get:Rule val animatorTestRule = AnimatorTestRule(this) - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val testScope: TestScope = kosmos.testScope private val fakeDeviceStateRepository = kosmos.fakeDeviceStateRepository private val powerInteractor = kosmos.powerInteractor @@ -93,7 +93,7 @@ class FoldLightRevealOverlayAnimationTest : SysuiTestCase() { fakeAnimationStatusRepository, mockControllerFactory, mockFoldLockSettingAvailabilityProvider, - mockJankMonitor + mockJankMonitor, ) foldLightRevealAnimation.init() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt index bafa8cf05a7f..da5622a2a8da 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt @@ -17,8 +17,10 @@ package com.android.systemui.user.data.repository +import android.app.admin.DevicePolicyManager import android.app.admin.devicePolicyManager import android.content.Intent +import android.content.applicationContext import android.content.pm.UserInfo import android.internal.statusbar.fakeStatusBarService import android.os.UserHandle @@ -77,10 +79,7 @@ class UserRepositoryImplTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) tracker = FakeUserTracker() - context.orCreateTestableResources.addOverride( - R.bool.config_userSwitchingMustGoThroughLoginScreen, - false, - ) + setUserSwitchingMustGoThroughLoginScreen(false) } @Test @@ -308,6 +307,117 @@ class UserRepositoryImplTest : SysuiTestCase() { job.cancel() } + @Test + fun isSecondaryUserLogoutEnabled_secondaryLogoutDisabled_alwaysFalse() = + testScope.runTest { + underTest = create(testScope.backgroundScope) + mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT) + setSecondaryUserLogoutEnabled(false) + setUpUsers(count = 2, selectedIndex = 0) + tracker.onProfileChanged() + + val secondaryUserLogoutEnabled by + collectLastValue(underTest.isSecondaryUserLogoutEnabled) + + assertThat(secondaryUserLogoutEnabled).isFalse() + + setUpUsers(count = 2, selectedIndex = 1) + tracker.onProfileChanged() + assertThat(secondaryUserLogoutEnabled).isFalse() + } + + @Test + fun isSecondaryUserLogoutEnabled_secondaryLogoutEnabled_NullLogoutUser_alwaysFalse() = + testScope.runTest { + underTest = create(testScope.backgroundScope) + mockLogoutUser(LogoutUserResult.NONE) + setSecondaryUserLogoutEnabled(true) + setUpUsers(count = 2, selectedIndex = 0) + tracker.onProfileChanged() + + val secondaryUserLogoutEnabled by + collectLastValue(underTest.isSecondaryUserLogoutEnabled) + + assertThat(secondaryUserLogoutEnabled).isFalse() + + setUpUsers(count = 2, selectedIndex = 1) + tracker.onProfileChanged() + assertThat(secondaryUserLogoutEnabled).isFalse() + } + + @Test + fun isSecondaryUserLogoutEnabled_secondaryLogoutEnabled_NonSystemLogoutUser_trueWhenNonSystem() = + testScope.runTest { + underTest = create(testScope.backgroundScope) + mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT) + setSecondaryUserLogoutEnabled(true) + setUpUsers(count = 2, selectedIndex = 0) + tracker.onProfileChanged() + + val secondaryUserLogoutEnabled by + collectLastValue(underTest.isSecondaryUserLogoutEnabled) + + assertThat(secondaryUserLogoutEnabled).isFalse() + + setUpUsers(count = 2, selectedIndex = 1) + tracker.onProfileChanged() + assertThat(secondaryUserLogoutEnabled).isTrue() + } + + @Test + fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenDisabled_alwaysFalse() = + testScope.runTest { + underTest = create(testScope.backgroundScope) + mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT) + setUserSwitchingMustGoThroughLoginScreen(false) + setUpUsers(count = 2, selectedIndex = 0) + tracker.onProfileChanged() + + val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled) + + assertThat(logoutToSystemUserEnabled).isFalse() + + setUpUsers(count = 2, selectedIndex = 1) + tracker.onProfileChanged() + assertThat(logoutToSystemUserEnabled).isFalse() + } + + @Test + fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenEnabled_NullLogoutUser_alwaysFalse() = + testScope.runTest { + underTest = create(testScope.backgroundScope) + mockLogoutUser(LogoutUserResult.NONE) + setUserSwitchingMustGoThroughLoginScreen(true) + setUpUsers(count = 2, selectedIndex = 0) + tracker.onProfileChanged() + + val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled) + + assertThat(logoutToSystemUserEnabled).isFalse() + + setUpUsers(count = 2, selectedIndex = 1) + tracker.onProfileChanged() + assertThat(logoutToSystemUserEnabled).isFalse() + } + + @Test + fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenEnabled_NonSystemLogoutUser_trueWhenNonSystem() = + testScope.runTest { + underTest = create(testScope.backgroundScope) + mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT) + setUserSwitchingMustGoThroughLoginScreen(true) + setUpUsers(count = 2, selectedIndex = 0) + tracker.onProfileChanged() + + val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled) + + assertThat(logoutToSystemUserEnabled).isFalse() + + setUpUsers(count = 2, selectedIndex = 1) + tracker.onProfileChanged() + assertThat(logoutToSystemUserEnabled).isTrue() + } + private fun createUserInfo(id: Int, isGuest: Boolean): UserInfo { val flags = 0 return UserInfo( @@ -354,6 +464,38 @@ class UserRepositoryImplTest : SysuiTestCase() { assertThat(model.isUserSwitcherEnabled).isEqualTo(expectedUserSwitcherEnabled) } + private fun setSecondaryUserLogoutEnabled(enabled: Boolean) { + whenever(devicePolicyManager.isLogoutEnabled).thenReturn(enabled) + broadcastDispatcher.sendIntentToMatchingReceiversOnly( + kosmos.applicationContext, + Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), + ) + } + + private fun setUserSwitchingMustGoThroughLoginScreen(enabled: Boolean) { + context.orCreateTestableResources.addOverride( + R.bool.config_userSwitchingMustGoThroughLoginScreen, + enabled, + ) + } + + private fun mockLogoutUser(result: LogoutUserResult) { + when (result) { + LogoutUserResult.NONE -> { + whenever(devicePolicyManager.logoutUser).thenReturn(null) + } + LogoutUserResult.NON_SYSTEM_CURRENT -> { + whenever(devicePolicyManager.logoutUser).thenAnswer { + if (tracker.userHandle != UserHandle.SYSTEM) { + tracker.userHandle + } else { + null + } + } + } + } + } + private fun create(scope: CoroutineScope): UserRepositoryImpl { return UserRepositoryImpl( appContext = context, @@ -373,4 +515,9 @@ class UserRepositoryImplTest : SysuiTestCase() { companion object { @JvmStatic private val IMMEDIATE = Dispatchers.Main.immediate } + + private enum class LogoutUserResult { + NONE, + NON_SYSTEM_CURRENT, + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt index b4ba41a5c524..a180d51ff0ba 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt @@ -27,7 +27,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.deviceStateManager -import com.android.systemui.kosmos.Kosmos +import com.android.systemui.testKosmos import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.Before @@ -39,7 +39,7 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class UtilsTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private val deviceStateManager = kosmos.deviceStateManager private lateinit var testableResources: TestableResources @@ -53,7 +53,7 @@ class UtilsTest : SysuiTestCase() { fun isFoldableReturnsFalse_overlayConfigurationValues() { testableResources.addOverride( com.android.internal.R.array.config_foldedDeviceStates, - intArrayOf() // empty array <=> device is not foldable + intArrayOf(), // empty array <=> device is not foldable ) whenever(deviceStateManager.supportedDeviceStates).thenReturn(listOf(DEFAULT_DEVICE_STATE)) assertFalse(Utils.isDeviceFoldable(testableResources.resources, deviceStateManager)) @@ -64,7 +64,7 @@ class UtilsTest : SysuiTestCase() { fun isFoldableReturnsFalse_deviceStateManager() { testableResources.addOverride( com.android.internal.R.array.config_foldedDeviceStates, - intArrayOf() // empty array <=> device is not foldable + intArrayOf(), // empty array <=> device is not foldable ) whenever(deviceStateManager.supportedDeviceStates).thenReturn(listOf(DEFAULT_DEVICE_STATE)) assertFalse(Utils.isDeviceFoldable(testableResources.resources, deviceStateManager)) @@ -75,7 +75,7 @@ class UtilsTest : SysuiTestCase() { fun isFoldableReturnsTrue_overlayConfigurationValues() { testableResources.addOverride( com.android.internal.R.array.config_foldedDeviceStates, - intArrayOf(FOLDED_DEVICE_STATE.identifier) + intArrayOf(FOLDED_DEVICE_STATE.identifier), ) whenever(deviceStateManager.supportedDeviceStates) .thenReturn(listOf(FOLDED_DEVICE_STATE, UNFOLDED_DEVICE_STATE)) @@ -87,7 +87,7 @@ class UtilsTest : SysuiTestCase() { fun isFoldableReturnsTrue_deviceStateManager() { testableResources.addOverride( com.android.internal.R.array.config_foldedDeviceStates, - intArrayOf(FOLDED_DEVICE_STATE.identifier) + intArrayOf(FOLDED_DEVICE_STATE.identifier), ) whenever(deviceStateManager.supportedDeviceStates) .thenReturn(listOf(FOLDED_DEVICE_STATE, UNFOLDED_DEVICE_STATE)) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt index f232d52615a4..93e5721e9b27 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt @@ -20,8 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.volume.panel.domain.availableCriteria import com.android.systemui.volume.panel.domain.defaultCriteria import com.android.systemui.volume.panel.domain.model.ComponentModel @@ -39,7 +39,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class ComponentsInteractorImplTest : SysuiTestCase() { - private val kosmos = Kosmos() + private val kosmos = testKosmos() private lateinit var underTest: ComponentsInteractor @@ -60,12 +60,7 @@ class ComponentsInteractorImplTest : SysuiTestCase() { fun componentsAvailability_checked() { with(kosmos) { testScope.runTest { - enabledComponents = - setOf( - BOTTOM_BAR, - COMPONENT_1, - COMPONENT_2, - ) + enabledComponents = setOf(BOTTOM_BAR, COMPONENT_1, COMPONENT_2) criteriaByKey = mapOf( BOTTOM_BAR to Provider { availableCriteria }, @@ -90,12 +85,7 @@ class ComponentsInteractorImplTest : SysuiTestCase() { fun noCriteria_fallbackToDefaultCriteria() { with(kosmos) { testScope.runTest { - enabledComponents = - setOf( - BOTTOM_BAR, - COMPONENT_1, - COMPONENT_2, - ) + enabledComponents = setOf(BOTTOM_BAR, COMPONENT_1, COMPONENT_2) criteriaByKey = mapOf( BOTTOM_BAR to Provider { availableCriteria }, diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt index 235475f6b202..0fc3470716fe 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt @@ -44,5 +44,5 @@ interface ClockEvents { fun onZenDataChanged(data: ZenData) /** Update reactive axes for this clock */ - fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) + fun onFontAxesChanged(axes: ClockAxisStyle) } diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt index 0cbc30d399d0..2147ca147b70 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt @@ -35,10 +35,54 @@ constructor( /** Font axes that can be modified on this clock */ val axes: List<ClockFontAxis> = listOf(), - /** List of font presets for this clock. Can be assigned directly. */ - val axisPresets: List<List<ClockFontAxisSetting>> = listOf(), + /** Presets for this clock. Null indicates the preset list should be disabled. */ + val presetConfig: AxisPresetConfig? = null, ) +data class AxisPresetConfig( + /** Groups of Presets. Each group can be used together in a single control. */ + val groups: List<Group>, + + /** Preset item currently being used, null when the current style is not a preset */ + val current: IndexedStyle? = null, +) { + /** The selected clock axis style, and its indices */ + data class IndexedStyle( + /** Index of the group that this clock axis style appears in */ + val groupIndex: Int, + + /** Index of the preset within the group */ + val presetIndex: Int, + + /** Reference to the style in question */ + val style: ClockAxisStyle, + ) + + /** A group of preset styles */ + data class Group( + /* List of preset styles in this group */ + val presets: List<ClockAxisStyle>, + + /* Icon to use when this preset-group is active */ + val icon: Drawable, + ) + + fun findStyle(style: ClockAxisStyle): IndexedStyle? { + groups.forEachIndexed { groupIndex, group -> + group.presets.forEachIndexed { presetIndex, preset -> + if (preset == style) { + return@findStyle IndexedStyle( + groupIndex = groupIndex, + presetIndex = presetIndex, + style = preset, + ) + } + } + } + return null + } +} + /** Represents an Axis that can be modified */ data class ClockFontAxis( /** Axis key, not user renderable */ @@ -62,19 +106,12 @@ data class ClockFontAxis( /** Description of the axis */ val description: String, ) { - fun toSetting() = ClockFontAxisSetting(key, currentValue) - companion object { - fun List<ClockFontAxis>.merge( - axisSettings: List<ClockFontAxisSetting> - ): List<ClockFontAxis> { - val result = mutableListOf<ClockFontAxis>() - for (axis in this) { - val setting = axisSettings.firstOrNull { axis.key == it.key } - val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis - result.add(output) - } - return result + fun List<ClockFontAxis>.merge(axisStyle: ClockAxisStyle): List<ClockFontAxis> { + return this.map { axis -> + axisStyle.get(axis.key)?.let { axis.copy(currentValue = it) } ?: axis + } + .toList() } } } diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt index e7b36626a810..cccc55835302 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt @@ -22,7 +22,7 @@ import org.json.JSONObject data class ClockSettings( val clockId: ClockId? = null, val seedColor: Int? = null, - val axes: List<ClockFontAxisSetting> = listOf(), + val axes: ClockAxisStyle = ClockAxisStyle(), ) { // Exclude metadata from equality checks var metadata: JSONObject = JSONObject() @@ -38,15 +38,15 @@ data class ClockSettings( put(KEY_CLOCK_ID, setting.clockId) put(KEY_SEED_COLOR, setting.seedColor) put(KEY_METADATA, setting.metadata) - put(KEY_AXIS_LIST, ClockFontAxisSetting.toJson(setting.axes)) + put(KEY_AXIS_LIST, ClockAxisStyle.toJson(setting.axes)) } } fun fromJson(json: JSONObject): ClockSettings { val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null - val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockFontAxisSetting::fromJson) - return ClockSettings(clockId, seedColor, axisList ?: listOf()).apply { + val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockAxisStyle::fromJson) + return ClockSettings(clockId, seedColor, axisList ?: ClockAxisStyle()).apply { metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject() } } @@ -54,64 +54,102 @@ data class ClockSettings( } @Keep -/** Axis setting value for a clock */ -data class ClockFontAxisSetting( - /** Axis key; matches ClockFontAxis.key */ - val key: String, +class ClockAxisStyle { + private val settings: MutableMap<String, Float> - /** Value to set this axis to */ - val value: Float, -) { - companion object { - private val KEY_AXIS_KEY = "key" - private val KEY_AXIS_VALUE = "value" + // Iterable would be implemented on ClockAxisStyle directly, + // but that doesn't appear to work with plugins/dynamic libs. + val items: Iterable<Map.Entry<String, Float>> + get() = settings.asIterable() - fun toJson(setting: ClockFontAxisSetting): JSONObject { - return JSONObject().apply { - put(KEY_AXIS_KEY, setting.key) - put(KEY_AXIS_VALUE, setting.value) - } - } + val isEmpty: Boolean + get() = settings.isEmpty() - fun toJson(settings: List<ClockFontAxisSetting>): JSONArray { - return JSONArray().apply { - for (axis in settings) { - put(toJson(axis)) - } - } + constructor(initialize: ClockAxisStyle.() -> Unit = {}) { + settings = mutableMapOf() + this.initialize() + } + + constructor(style: ClockAxisStyle) { + settings = style.settings.toMutableMap() + } + + constructor(items: Map<String, Float>) { + settings = items.toMutableMap() + } + + constructor(key: String, value: Float) { + settings = mutableMapOf(key to value) + } + + constructor(items: List<ClockFontAxis>) { + settings = items.associate { it.key to it.currentValue }.toMutableMap() + } + + fun copy(initialize: ClockAxisStyle.() -> Unit): ClockAxisStyle { + return ClockAxisStyle(this).apply { initialize() } + } + + operator fun get(key: String): Float? = settings[key] + + operator fun set(key: String, value: Float) = put(key, value) + + fun put(key: String, value: Float) { + settings.put(key, value) + } + + fun toFVar(): String { + val sb = StringBuilder() + for (axis in settings) { + if (sb.length > 0) sb.append(", ") + sb.append("'${axis.key}' ${axis.value.toInt()}") } + return sb.toString() + } - fun fromJson(jsonObj: JSONObject): ClockFontAxisSetting { - return ClockFontAxisSetting( - key = jsonObj.getString(KEY_AXIS_KEY), - value = jsonObj.getDouble(KEY_AXIS_VALUE).toFloat(), - ) + fun copyWith(replacements: ClockAxisStyle): ClockAxisStyle { + val result = ClockAxisStyle(this) + for ((key, value) in replacements.settings) { + result[key] = value } + return result + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ClockAxisStyle) return false + return settings == other.settings + } - fun fromJson(jsonArray: JSONArray): List<ClockFontAxisSetting> { - val result = mutableListOf<ClockFontAxisSetting>() + companion object { + private val KEY_AXIS_KEY = "key" + private val KEY_AXIS_VALUE = "value" + + fun fromJson(jsonArray: JSONArray): ClockAxisStyle { + val result = ClockAxisStyle() for (i in 0..jsonArray.length() - 1) { val obj = jsonArray.getJSONObject(i) if (obj == null) continue - result.add(fromJson(obj)) + + result.put( + key = obj.getString(KEY_AXIS_KEY), + value = obj.getDouble(KEY_AXIS_VALUE).toFloat(), + ) } return result } - fun List<ClockFontAxisSetting>.toFVar(): String { - val sb = StringBuilder() - for (axis in this) { - if (sb.length > 0) sb.append(", ") - sb.append("'${axis.key}' ${axis.value.toInt()}") + fun toJson(style: ClockAxisStyle): JSONArray { + return JSONArray().apply { + for ((key, value) in style.settings) { + put( + JSONObject().apply { + put(KEY_AXIS_KEY, key) + put(KEY_AXIS_VALUE, value) + } + ) + } } - return sb.toString() - } - - fun List<ClockFontAxisSetting>.replace( - replacements: List<ClockFontAxisSetting> - ): List<ClockFontAxisSetting> { - var remaining = this.filterNot { lhs -> replacements.any { rhs -> lhs.key == rhs.key } } - return remaining + replacements } } } diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml index 609a517c6734..0c844ab3d223 100644 --- a/packages/SystemUI/res-keyguard/values-it/strings.xml +++ b/packages/SystemUI/res-keyguard/values-it/strings.xml @@ -23,7 +23,7 @@ <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Inserisci il PIN"</string> <string name="keyguard_enter_pin" msgid="8114529922480276834">"Inserisci il PIN"</string> <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Inserisci la sequenza"</string> - <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Inserisci la sequenza"</string> + <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Traccia la sequenza"</string> <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Inserisci la password"</string> <string name="keyguard_enter_password" msgid="6483623792371009758">"Inserisci la password"</string> <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Scheda non valida."</string> diff --git a/packages/SystemUI/res/color/brightness_slider_track.xml b/packages/SystemUI/res/color/brightness_slider_track.xml new file mode 100644 index 000000000000..c6e9b65fb7e8 --- /dev/null +++ b/packages/SystemUI/res/color/brightness_slider_track.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@android:color/system_neutral2_500" android:lStar="40" /> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml index 88d3ecb3f423..d38da7b766c1 100644 --- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml +++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml @@ -25,7 +25,7 @@ <shape> <size android:height="@dimen/rounded_slider_track_width" /> <corners android:radius="@dimen/rounded_slider_track_corner_radius" /> - <solid android:color="@androidprv:color/customColorShadeInactive" /> + <solid android:color="@color/brightness_slider_track" /> </shape> </inset> </item> diff --git a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml index 949a6abb9b9d..a1b26fc9bb40 100644 --- a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml +++ b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml @@ -85,13 +85,49 @@ android:longClickable="false"/> </LinearLayout> + <LinearLayout + android:id="@+id/input_routing_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/preset_layout" + android:layout_marginTop="@dimen/hearing_devices_layout_margin" + android:orientation="vertical" + android:visibility="gone"> + <TextView + android:id="@+id/input_routing_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin" + android:layout_marginEnd="@dimen/bluetooth_dialog_layout_margin" + android:paddingStart="@dimen/hearing_devices_small_title_padding_horizontal" + android:text="@string/hearing_devices_input_routing_label" + android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textSize="14sp" + android:gravity="center_vertical" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textDirection="locale"/> + <Spinner + android:id="@+id/input_routing_spinner" + style="@style/BluetoothTileDialog.Device" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:layout_marginTop="4dp" + android:paddingStart="0dp" + android:paddingEnd="0dp" + android:background="@drawable/hearing_devices_spinner_background" + android:popupBackground="@drawable/hearing_devices_spinner_popup_background" + android:dropDownWidth="match_parent" + android:longClickable="false"/> + </LinearLayout> + <com.android.systemui.accessibility.hearingaid.AmbientVolumeLayout android:id="@+id/ambient_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/preset_layout" + app:layout_constraintTop_toBottomOf="@id/input_routing_layout" android:layout_marginTop="@dimen/hearing_devices_layout_margin" /> <LinearLayout diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 62363358f663..bc08a3e2c628 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgewing"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Regs"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgewing"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Linker omgewing"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Regter omgewing"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Vou uit na links- en regsgeskeide kontroles"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Vou in na verenigde kontrole"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Demp omgewing"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ontdemp omgewing"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nutsgoed"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Intydse Onderskrifte"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Instellings"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokkeer toestelmikrofoon?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokkeer toestelkamera?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aan – gesiggegrond"</string> <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string> <string name="inline_ok_button" msgid="603075490581280343">"Pas toe"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Skakel kennisgewings af"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Verstek"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Outomaties"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gebruik verdeelde skerm met app aan die regterkant"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gebruik verdeelde skerm met app aan die linkerkant"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gebruik volskerm"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gebruik werkskermvensters"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skakel oor na app regs of onder terwyl jy verdeelde skerm gebruik"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skakel oor na app links of bo terwyl jy verdeelde skerm gebruik"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Voeg by posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisie is ongeldig."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Teël is reeds bygevoeg"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Teël is bygevoeg"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Teël is verwyder"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kitsinstellingswysiger."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Versteek hierdie mediakontrole vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Die huidige mediasessie kan nie versteek word nie."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Versteek"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> speel tans vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml index fde914fa292c..64912d4ff9c1 100644 --- a/packages/SystemUI/res/values-af/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Af"</item> <item msgid="4875147066469902392">"Aan"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Onbeskikbaar"</item> <item msgid="5044688398303285224">"Af"</item> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index e180d114a75a..1c158b388d74 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"በዙሪያ ያሉ"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ግራ"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ቀኝ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"በዙሪያ ያሉ"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"በግራ ዙሪያ ያሉ"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"በቀኝ ዙሪያ ያሉ"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ወደ ግራ እና ቀኝ የተለያዩ ቁጥጥሮች ዘርጋ"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ወደ የተዋሃደ ቁጥጥር ሰብስብ"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"በዙሪያ ያሉትን ድምፀ-ከል አድርግ"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"በዙሪያ ያሉትን ድምፅ-ከል አንሳ"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"መሣሪያዎች"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"የቀጥታ መግለጫ ጽሑፍ"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ቅንብሮች"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"ማስታወሻ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"የመሣሪያ ማይክሮፎን እገዳ ይነሳ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"የመሣሪያ ካሜራ እገዳ ይነሳ?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"በርቷል - መልክ ላይ የተመሠረተ"</string> <string name="inline_done_button" msgid="6043094985588909584">"ተከናውኗል"</string> <string name="inline_ok_button" msgid="603075490581280343">"ተግብር"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ማሳወቂያዎችን አጥፋ"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ፀጥ ያለ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ነባሪ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ራስ-ሰር"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"መተግበሪያ በስተቀኝ ላይ ሆኖ የተከፈለ ማያ ገፅን ይጠቀሙ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"መተግበሪያ በስተግራ ላይ ሆኖ የተከፈለ ማያ ገፅን ይጠቀሙ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ሙሉ ገፅ ዕይታን ይጠቀሙ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"የዴስክቶፕ መስኮት ይጠቀሙ"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከታች ወዳለ መተግበሪያ ይቀይሩ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከላይ ወዳለ መተግበሪያ ይቀይሩ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"በተከፈለ ማያ ገጽ ወቅት፡- መተግበሪያን ከአንዱ ወደ ሌላው ተካ"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ቦታ አክል"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"አቀማመጡ ተቀባይነት የለውም።"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"የ<xliff:g id="POSITION">%1$d</xliff:g> አቀማመጥ"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ሰቅ አስቀድሞ ታክሏል"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ሰቅ ታክሏል"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ሰቅ ተወግዷል"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"የፈጣን ቅንብሮች አርታዒ።"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የዚህ ሚዲያ መቆጣጠሪያ ይደበቅ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"የአሁኑ የሚዲያ ክፍለ ጊዜ ሊደበቅ አይቻልም።"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ደብቅ"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> እየተጫወተ ነው"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ከ<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml index f8e7a4387411..24666e7c12f7 100644 --- a/packages/SystemUI/res/values-am/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ጠፍቷል"</item> <item msgid="4875147066469902392">"በርቷል"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"አይገኝም"</item> <item msgid="5044688398303285224">"ጠፍቷል"</item> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 416eee837b22..b494f4ec5fad 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"إعادة الأصوات المحيطة"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"الأدوات"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"النسخ النصي التلقائي"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"الإعدادات"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"ملاحظات"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"هل تريد إزالة حظر ميكروفون الجهاز؟"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"هل تريد إزالة حظر كاميرا الجهاز؟"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"تفعيل - استنادًا للوجه"</string> <string name="inline_done_button" msgid="6043094985588909584">"تمّ"</string> <string name="inline_ok_button" msgid="603075490581280343">"تطبيق"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"إيقاف الإشعارات"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"إشعارات صامتة"</string> <string name="notification_alert_title" msgid="3656229781017543655">"تلقائية"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"تلقائي"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"استخدام \"وضع تقسيم الشاشة\" مع تثبيت التطبيق على اليمين"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"استخدام \"وضع تقسيم الشاشة\" مع تثبيت التطبيق على اليسار"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"استخدام وضع ملء الشاشة"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"استخدام وضع عرض النوافذ على سطح المكتب"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"التبديل إلى التطبيق على اليسار أو الأسفل أثناء استخدام \"تقسيم الشاشة\""</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"التبديل إلى التطبيق على اليمين أو الأعلى أثناء استخدام \"تقسيم الشاشة\""</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</string> @@ -1003,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"الإضافة إلى الموضع <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"الموضِع غير صالح."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"الموضع: <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"سبق أن تمت إضافة شاشة المعلومات"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"تمت إضافة البطاقة."</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"تمت إزالة البطاقة."</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"برنامج تعديل الإعدادات السريعة."</string> @@ -1205,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"هل تريد إخفاء عنصر التحكم في الوسائط هذا للتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"لا يمكن إخفاء جلسة الوسائط الحالية."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"إخفاء"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"يتم تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> من إجمالي <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml index aac5a355aa78..31607b9548a4 100644 --- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"الميزة غير مفعّلة"</item> <item msgid="4875147066469902392">"الميزة مفعّلة"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"الميزة غير متاحة"</item> <item msgid="5044688398303285224">"الميزة غير مفعّلة"</item> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 4340f2132e78..d3ec875711f5 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"আশ-পাশ"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাওঁফাল"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"সোঁফাল"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"আশে-পাশে থকা"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"বাওঁফালে আশে-পাশে থকা"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"সোঁফালে আশে-পাশে থকা"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"বাওঁ আৰু সোঁফালৰ পৃথক কৰা নিয়ন্ত্ৰণলৈ সংকোচন কৰক"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"একত্ৰিত নিয়ন্ত্ৰণলৈ সংকোচন কৰক"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"আশ-পাশৰ ধ্বনি মিউট কৰক"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"আশ-পাশৰ ধ্বনি আনমিউট কৰক"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"সঁজুলি"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ কেপশ্বন"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ছেটিং"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"টোকা"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইচৰ মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইচৰ কেমেৰা অৱৰোধৰ পৰা আঁতৰাবনে?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"অন আছে - মুখাৱয়ব ভিত্তিক"</string> <string name="inline_done_button" msgid="6043094985588909584">"কৰা হ’ল"</string> <string name="inline_ok_button" msgid="603075490581280343">"প্ৰয়োগ কৰক"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"জাননী অফ কৰক"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"নীৰৱ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ডিফ’ল্ট"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"স্বয়ংক্ৰিয়"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"সোঁফালে থকা এপ্টোৰ সৈতে বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰক"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"বাওঁফালে থকা এপ্টোৰ সৈতে বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰক"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰক"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ডেস্কটপ ৱিণ্ড’ৱিং ব্যৱহাৰ কৰক"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত সোঁফালে অথবা তলত থকা এপলৈ সলনি কৰক"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত বাওঁফালে অথবা ওপৰত থকা এপলৈ সলনি কৰক"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"বিভাজিত স্ক্ৰীনৰ ব্যৱহাৰ কৰাৰ সময়ত: কোনো এপ্ এখন স্ক্ৰীনৰ পৰা আনখনলৈ নিয়ক"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থানত যোগ দিয়ক"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"স্থান অমান্য।"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থান"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ইতিমধ্যে টাইল যোগ দিয়া হৈছে"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ দিয়া হৈছে"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল আঁতৰোৱা হৈছে"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ক্ষিপ্ৰ ছেটিঙৰ সম্পাদক।"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে এই মিডিয়া নিয়ন্ত্ৰণটো লুকুৱাবনে?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"বৰ্তমানৰ মিডিয়াৰ ছেশ্বনটো লুকুৱাব নোৱাৰি।"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকুৱাওক"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিং"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ হৈ আছে"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ৰ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml index ba30c1e7db0a..39bd63e5d27a 100644 --- a/packages/SystemUI/res/values-as/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"অফ আছে"</item> <item msgid="4875147066469902392">"অন কৰা আছে"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"উপলব্ধ নহয়"</item> <item msgid="5044688398303285224">"অফ আছে"</item> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 226c39dad194..9655ab75e61b 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ətraf mühit"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Sağ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ətraf mühit"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Sol tərəf"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Sağ tərəf"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Sola və sağa ayrılmış idarəetmələr üçün genişləndirin"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Vahid nəzarət üçün yığcamlaşdırın"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ətraf mühiti səssiz edin"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ətraf mühiti səssiz rejimdən çıxarın"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alətlər"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ayarlar"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qeyd"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktiv - Üz əsaslı"</string> <string name="inline_done_button" msgid="6043094985588909584">"Hazırdır"</string> <string name="inline_ok_button" msgid="603075490581280343">"Tətbiq edin"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirişləri deaktiv edin"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Səssiz"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Defolt"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Tətbiq sağda olmaqla bölünmüş ekranı istifadə edin"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Tətbiq solda olmaqla bölünmüş ekranı istifadə edin"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Tam ekrandan istifadə edin"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Masaüstü pəncərə rejimindən istifadə edin"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran istifadə edərkən sağda və ya aşağıda tətbiqə keçin"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran istifadə edərkən solda və ya yuxarıda tətbiqə keçin"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişin"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə əlavə edin"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Mövqe yanlışdır."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Mozaik əlavə edilib"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Mozaik əlavə edilib"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Mozaik silinib"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sürətli ayarlar redaktoru."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün bu media nizamlayıcısı gizlədilsin?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Cari media sessiyası gizlədilə bilməz."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizlədin"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudulur"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml index 74b95e2842e2..a78e67268f82 100644 --- a/packages/SystemUI/res/values-az/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Deaktiv"</item> <item msgid="4875147066469902392">"Aktiv"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Əlçatan deyil"</item> <item msgid="5044688398303285224">"Deaktiv"</item> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 0d7619d36e75..f46399659530 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okruženje"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Levo okruženje"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Desno okruženje"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširi na kontrole razdvojene na levu i desnu stranu"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Skupi u jedinstvenu kontrolu"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključi zvuk okruženja"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Uključi zvuk okruženja"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatke"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titl uživo"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Podešavanja"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Beleška"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na osnovu lica"</string> <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string> <string name="inline_ok_button" msgid="603075490581280343">"Primeni"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obaveštenja"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Podrazumevano"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Koristi podeljeni ekran sa aplikacijom s desne strane"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Koristi podeljeni ekran sa aplikacijom s leve strane"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Koristi prikaz preko celog ekrana"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Koristi prozorski prikaz na računaru"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređi u aplikaciju zdesna ili ispod dok je podeljen ekran"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju sleva ili iznad dok koristite podeljeni ekran"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"U režimu podeljenog ekrana: zamena jedne aplikacije drugom"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicija je nevažeća."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Pločica je već dodata"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pločica je dodata"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pločica je uklonjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml index 51b667c3fafd..bbfcf840e53f 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Isključeno"</item> <item msgid="4875147066469902392">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nedostupno"</item> <item msgid="5044688398303285224">"Isključeno"</item> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 809b60b712a1..2ece7bd3900e 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -33,7 +33,7 @@ <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, дзякуй"</string> <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартны рэжым"</string> <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Максімальная"</string> - <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аўтаматычны паварот экрана"</string> + <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аўтапаварот экрана"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Даць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nУ гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту прыладу USB."</string> <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Дазволіць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string> @@ -333,7 +333,7 @@ <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Уключэнне…"</string> <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Не ўдаецца адрэгуляваць яркасць, бо яна кантралюецца верхняй праграмай"</string> <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string> - <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string> + <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтапаварот экрана"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string> <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Экранная застаўка"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ да камеры"</string> @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Навакольныя гукі"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левы бок"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Правы бок"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Навакольныя гукі"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Навакольныя гукі злева"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Навакольныя гукі справа"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Зрабіць левую і правую панэлі кіравання"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Зрабіць адну панэль кіравання"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Выключыць навакольныя гукі"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Уключыць навакольныя гукі"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменты"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Аўтаматычныя субцітры"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Налады"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нататка"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблакіраваць мікрафон прылады?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблакіраваць камеру прылады?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Уключана – З улікам паставы галавы"</string> <string name="inline_done_button" msgid="6043094985588909584">"Гатова"</string> <string name="inline_ok_button" msgid="603075490581280343">"Прымяніць"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Выключыць апавяшчэнні"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Бязгучны рэжым"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Стандартна"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Аўтаматычна"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Падзяліць экран і памясціць праграму справа"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Падзяліць экран і памясціць праграму злева"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Выкарыстоўваць поўнаэкранны рэжым"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Выкарыстоўваць рэжым вокнаў працоўнага стала"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пераключыцца на праграму справа або ўнізе на падзеленым экране"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пераключыцца на праграму злева або ўверсе на падзеленым экране"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"У рэжыме падзеленага экрана замяніць адну праграму на іншую"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Дадаць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Няправільнае месца."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Пазіцыя <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плітка ўжо дададзена"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плітка дададзена"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плітка выдалена"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Рэдактар хуткіх налад."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Схаваць гэту панэль мультымедыя для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Не ўдалося схаваць бягучы сеанс мультымедыя."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Схаваць"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Налады"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"У праграме \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\" прайграецца кампазіцыя \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml index cbbfe925c893..e6b35439ce44 100644 --- a/packages/SystemUI/res/values-be/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Выключана"</item> <item msgid="4875147066469902392">"Уключана"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Недаступна"</item> <item msgid="5044688398303285224">"Выключана"</item> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 9f7a9cdda45b..3ab943a658e6 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Включване на околните звуци"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменти"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Надписи на живо"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Настройки"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Бележка"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се отблокира ли микрофонът на устройството?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се отблокира ли камерата на устройството?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Вкл. – въз основа на лицето"</string> <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string> <string name="inline_ok_button" msgid="603075490581280343">"Прилагане"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Изключване на известията"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Тих режим"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Стандартно"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Използване на разделен екран с приложението вдясно"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Използване на разделен екран с приложението вляво"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Използване режима на цял екран"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Използване на режима за настолни компютри"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Превключване към приложението вдясно/отдолу в режима на разделен екран"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Превключване към приложението вляво/отгоре в режима на разделен екран"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"При разделен екран: замяна на дадено приложение с друго"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Скриване на мултимед. контрола за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Текущата сесия за мултимедия не бе скрита."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се възпроизвежда от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> от <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml index 636585d2a22b..b46d4dffb5fd 100644 --- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Изкл."</item> <item msgid="4875147066469902392">"Вкл."</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Не е налице"</item> <item msgid="5044688398303285224">"Изкл."</item> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index f1d97700c6f3..4ab650edc56d 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"সারাউন্ডিং"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাঁদিক"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ডানদিক"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"সারাউন্ডিং"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"লেফ্ট সারাউন্ডিং"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"রাইট সারাউন্ডিং"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"বাঁদিক ও ডানদিকের আলাদা করা কন্ট্রোল বড় করুন"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ইউনিফায়েড কন্ট্রোল আড়াল করুন"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"সারাউন্ডিং মিউট করুন"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"সারাউন্ডিং আনমিউট করুন"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"টুল"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ ক্যাপশন"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"সেটিংস"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"মনে রাখবেন"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইসের মাইক্রোফোন আনব্লক করতে চান?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইসের ক্যামেরা আনব্লক করতে চান?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"চালু আছে - মুখের হিসেবে"</string> <string name="inline_done_button" msgid="6043094985588909584">"হয়ে গেছে"</string> <string name="inline_ok_button" msgid="603075490581280343">"প্রয়োগ করুন"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"বিজ্ঞপ্তি বন্ধ করুন"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"সাইলেন্ট"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ডিফল্ট"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"অটোমেটিক"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ডানদিকে বর্তমান অ্যাপে স্প্লিট স্ক্রিন ব্যবহার করুন"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"বাঁদিকে বর্তমান অ্যাপে স্প্লিট স্ক্রিন ব্যবহার করুন"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ফুল-স্ক্রিন মোড ব্যবহার করুন"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ডেস্কটপ উইন্ডোয়িং ব্যবহার করুন"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"স্প্লিট স্ক্রিন ব্যবহার করার সময় ডানদিকের বা নিচের অ্যাপে পাল্টে নিন"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"স্প্লিট স্ক্রিন ব্যবহার করার সময় বাঁদিকের বা উপরের অ্যাপে পাল্টে নিন"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"\'স্প্লিট স্ক্রিন\' থাকাকালীন: একটি অ্যাপ থেকে অন্যটিতে পাল্টান"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>-এ যোগ করুন"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"পজিশন সঠিক নয়।"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"টাইল আগেই যোগ করা হয়েছে"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ করা হয়েছে"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল সরানো হয়েছে"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"দ্রুত সেটিংস সম্পাদক৷"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর মিডিয়া কন্ট্রোল লুকিয়ে রাখতে চান?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"বর্তমান মিডিয়া সেশন লুকিয়ে রাখা যাবে না।"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকান"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>টির মধ্যে <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>টি"</string> diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml index 08231e4f8649..852986ccb0fd 100644 --- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"বন্ধ আছে"</item> <item msgid="4875147066469902392">"চালু আছে"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"উপলভ্য নেই"</item> <item msgid="5044688398303285224">"বন্ধ আছে"</item> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 57b83d933f53..afa877ee5c0a 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okruženje"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Lijevo okruženje"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Desno okruženje"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširivanje u zasebne kontrole ulijevo i udesno"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sužavanje u objedinjenu kontrolu"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključivanje zvuka okruženja"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Uključivanje zvuka okruženja"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Postavke"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Bilješka"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokirati mikrofon uređaja?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokirati kameru uređaja?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na osnovu lica"</string> <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string> <string name="inline_ok_button" msgid="603075490581280343">"Primijeni"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obavještenja"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Korištenje podijeljenog ekrana s aplikacijom na desnoj strani"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Korištenje podijeljenog ekrana s aplikacijom na lijevoj strani"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Korištenje prikaza preko cijelog ekrana"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Korištenje prikaza u prozorima na računaru"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak u aplikaciju desno ili ispod uz podijeljeni ekran"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju lijevo ili iznad dok koristite podijeljeni ekran"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nevažeći položaj."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kartica je već dodana"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivanje brzih postavki"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Sakriti kontrolu medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutna sesija medija se ne može sakriti."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Pjesma <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se reproducira pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml index 51b667c3fafd..bbfcf840e53f 100644 --- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Isključeno"</item> <item msgid="4875147066469902392">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nedostupno"</item> <item msgid="5044688398303285224">"Isključeno"</item> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index d2f942eeb628..3e43c7924678 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Deixa de silenciar l\'entorn"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eines"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítols instantanis"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configuració"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activat: basat en cares"</string> <string name="inline_done_button" msgid="6043094985588909584">"Fet"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplica"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactiva les notificacions"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silenci"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utilitzar la pantalla dividida amb l\'aplicació a la dreta"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utilitzar la pantalla dividida amb l\'aplicació a l\'esquerra"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utilitza la pantalla completa"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Utilitza l\'enfinestrament d\'escriptori"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Canvia a l\'aplicació de la dreta o de sota amb la pantalla dividida"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Canvia a l\'aplicació de l\'esquerra o de dalt amb la pantalla dividida"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string> @@ -1003,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Afegeix a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"La posició no és vàlida."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posició <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"La targeta ja s\'ha afegit"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"El mosaic s\'ha afegit"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"El mosaic s\'ha suprimit"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuració ràpida."</string> @@ -1205,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Amagar aquest control multimèdia per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"La sessió multimèdia actual no es pot amagar."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) s\'està reproduint des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml index 3b0b9d7cc434..5094d57a0ecf 100644 --- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desactivat"</item> <item msgid="4875147066469902392">"Activat"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"No disponible"</item> <item msgid="5044688398303285224">"Desactivat"</item> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 5149f9d8c1af..f374913a56cf 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolí"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vlevo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Vpravo"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okolí"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Okolí vlevo"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Okolí vpravo"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozbalit na samostatné ovládání levé a pravé strany"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sbalit na sjednocené ovládání"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ztlumit okolí"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Zapnout zvuk okolí"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okamžité titulky"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Nastavení"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Zapnuto – podle obličeje"</string> <string name="inline_done_button" msgid="6043094985588909584">"Hotovo"</string> <string name="inline_ok_button" msgid="603075490581280343">"Použít"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Vypnout oznámení"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Tichý režim"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Výchozí"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Použít rozdělenou obrazovku s aplikací vpravo"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Použít rozdělenou obrazovku s aplikací vlevo"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Použít celou obrazovku"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Používat okna jako na počítači"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Přepnout na aplikaci vpravo nebo dole v režimu rozdělené obrazovky"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Přepnout na aplikaci vlevo nebo nahoře v režimu rozdělené obrazovky"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Přidat dlaždici na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozice není platná."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Karta byla už přidána"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dlaždice byla přidána"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Dlaždice byla odstraněna"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rychlého nastavení"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Skrýt toto ovládání médií aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuální mediální relaci nelze skrýt."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrýt"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> hrajte z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml index 49770328c94d..0c7db6763eeb 100644 --- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Vypnuto"</item> <item msgid="4875147066469902392">"Zapnuto"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nedostupné"</item> <item msgid="5044688398303285224">"Vypnuto"</item> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index baf010ddae5d..0875aad0986e 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Højre"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgivelser"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Omgivelser til venstre"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Omgivelser til højre"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Udvid til adskilte styringselementer til venstre og højre"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Minimer til samlet styringselement"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ignorer omgivelser"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ignorer ikke omgivelser"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Værktøjer"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstning"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Indstillinger"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du fjerne blokeringen af enhedens mikrofon?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du fjerne blokeringen af enhedens kamera?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Til – ansigtsbaseret"</string> <string name="inline_done_button" msgid="6043094985588909584">"Udfør"</string> <string name="inline_ok_button" msgid="603075490581280343">"Anvend"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Deaktiver notifikationer"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Lydløs"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Brug opdelt skærm med appen til højre"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Brug opdelt skærm med appen til venstre"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Brug fuld skærm"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Brug vinduer på skrivebordet"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skift til en app til højre eller nedenfor, når du bruger opdelt skærm"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skift til en app til venstre eller ovenfor, når du bruger opdelt skærm"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Ved opdelt skærm: Udskift én app med en anden"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Føj til lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positionen er ugyldig."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Handlingsfeltet er allerede tilføjet"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Feltet blev tilføjet"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Feltet blev fjernet"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsværktøj til Kvikmenu."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Vil du skjule denne mediefunktion for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuelle mediesession kan ikke skjules."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspilles via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml index af6dafbc614e..5558b0b5433f 100644 --- a/packages/SystemUI/res/values-da/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Fra"</item> <item msgid="4875147066469902392">"Til"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Ikke tilgængelig"</item> <item msgid="5044688398303285224">"Fra"</item> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 8c8e994dd9cc..8b783fdcc161 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umgebungsgeräusche"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Rechts"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Umgebungsgeräusche"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Umgebungsgeräusche links"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Umgebungsgeräusche rechts"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"In ein linkes und ein rechtes Steuerfeld maximieren"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zu einem einzigen Steuerfeld minimieren"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Umgebungsgeräusche stummschalten"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Stummschaltung der Umgebungsgeräusche aufheben"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatische Untertitel"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Einstellungen"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notiz"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blockierung des Gerätemikrofons aufheben?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blockierung der Gerätekamera aufheben?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"An – gesichtsbasiert"</string> <string name="inline_done_button" msgid="6043094985588909584">"Fertig"</string> <string name="inline_ok_button" msgid="603075490581280343">"Anwenden"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Benachrichtigungen deaktivieren"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Lautlos"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Splitscreen mit der App auf der rechten Seite nutzen"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Splitscreen mit der App auf der linken Seite nutzen"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Vollbildmodus verwenden"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Desktop-Windowing verwenden"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Im Splitscreen-Modus zu einer App rechts oder unten wechseln"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Im Splitscreen-Modus zu einer App links oder oben wechseln"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Im Splitscreen: eine App durch eine andere ersetzen"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Zur Position <xliff:g id="POSITION">%1$d</xliff:g> hinzufügen"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position ist ungültig."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kachel bereits hinzugefügt"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ansicht hinzugefügt"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ansicht entfernt"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor für Schnelleinstellungen."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Mediensteuerung für <xliff:g id="APP_NAME">%1$s</xliff:g> ausblenden?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Die Mediensitzung kann nicht ausgeblendet werden."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wird gerade über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergegeben"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> von <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml index 44734aec80e9..2d4d1b6eb3da 100644 --- a/packages/SystemUI/res/values-de/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Aus"</item> <item msgid="4875147066469902392">"An"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nicht verfügbar"</item> <item msgid="5044688398303285224">"Aus"</item> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index daebf7006498..c1a9a3a4c19d 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ήχοι περιβάλλοντος"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Αριστερά"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Δεξιά"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ήχοι περιβάλλοντος"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ήχοι περιβάλλοντος στα αριστερά"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ήχοι περιβάλλοντος στα δεξιά"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Ανάπτυξη σε ξεχωριστά στοιχεία ελέγχου αριστερά και δεξιά"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Σύμπτυξη σε ενοποιημένο στοιχείο ελέγχου"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Σίγαση ήχων περιβάλλοντος"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Κατάργηση σίγασης ήχων περιβάλλοντος"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Εργαλεία"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ζωντανοί υπότιτλοι"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ρυθμίσεις"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Σημείωση"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Κατάργηση αποκλεισμού μικροφώνου συσκευής;"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Κατάργηση αποκλεισμού κάμερας συσκευής;"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ενεργό - Βάσει προσώπου"</string> <string name="inline_done_button" msgid="6043094985588909584">"Τέλος"</string> <string name="inline_ok_button" msgid="603075490581280343">"Εφαρμογή"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Απενεργοποίηση ειδοποιήσεων"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Σίγαση"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Προεπιλογή"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Αυτόματο"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Χρήση διαχωρισμού οθόνης με την εφαρμογή στα δεξιά"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Χρήση διαχωρισμού οθόνης με την εφαρμογή στα αριστερά"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Χρήση πλήρους οθόνης"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Χρήση της λειτουργίας προσαρμογής σε παράθυρο στην επιφάνεια εργασίας"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Εναλλαγή στην εφαρμογή δεξιά ή κάτω κατά τη χρήση διαχωρισμού οθόνης"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Εναλλαγή σε εφαρμογή αριστερά ή επάνω κατά τη χρήση διαχωρισμού οθόνης"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Κατά τον διαχωρισμό οθόνης: αντικατάσταση μιας εφαρμογής με άλλη"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Προσθήκη στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Μη έγκυρη θέση."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Το πλακίδιο έχει ήδη προστεθεί"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Το πλακίδιο προστέθηκε"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Το πλακίδιο καταργήθηκε"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Επεξεργασία γρήγορων ρυθμίσεων."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Απόκρυψη στοιχ. ελέγχου μέσων για <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Αδυναμία απόκρ. τρέχουσας περιόδ. λειτουργ. μέσου."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Γίνεται αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> από <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml index b649db4c7e3b..76e70719d11f 100644 --- a/packages/SystemUI/res/values-el/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Ανενεργό"</item> <item msgid="4875147066469902392">"Ενεργό"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Μη διαθέσιμο"</item> <item msgid="5044688398303285224">"Ανενεργός"</item> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 875b21a72166..1fee916f670e 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Settings"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string> <string name="inline_done_button" msgid="6043094985588909584">"Done"</string> <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use fullscreen"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml index e17eeb2b6023..34580ebc9b99 100644 --- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Off"</item> <item msgid="4875147066469902392">"On"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Unavailable"</item> <item msgid="5044688398303285224">"Off"</item> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 4e4295ab56a2..318f0b43332e 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -794,7 +794,7 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On - Face-based"</string> <string name="inline_done_button" msgid="6043094985588909584">"Done"</string> <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string> + <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Turn off"</string> <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string> @@ -905,8 +905,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use full screen"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to app on right or below while using split screen"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to app on left or above while using split screen"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: replace an app from one to another"</string> @@ -1203,7 +1202,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml index e17eeb2b6023..3014e6207e7d 100644 --- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml @@ -56,6 +56,11 @@ <item msgid="5376619709702103243">"Off"</item> <item msgid="4875147066469902392">"On"</item> </string-array> + <string-array name="tile_states_modes_dnd"> + <item msgid="6509540227356524582">"Unavailable"</item> + <item msgid="8589336868985358191">"Off"</item> + <item msgid="726072717827778234">"On"</item> + </string-array> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Unavailable"</item> <item msgid="5044688398303285224">"Off"</item> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 875b21a72166..1fee916f670e 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Settings"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string> <string name="inline_done_button" msgid="6043094985588909584">"Done"</string> <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use fullscreen"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml index e17eeb2b6023..34580ebc9b99 100644 --- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Off"</item> <item msgid="4875147066469902392">"On"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Unavailable"</item> <item msgid="5044688398303285224">"Off"</item> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 875b21a72166..1fee916f670e 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Settings"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string> <string name="inline_done_button" msgid="6043094985588909584">"Done"</string> <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use fullscreen"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml index e17eeb2b6023..34580ebc9b99 100644 --- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Off"</item> <item msgid="4875147066469902392">"On"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Unavailable"</item> <item msgid="5044688398303285224">"Off"</item> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index c2dd040426a8..486b43a2e867 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activa - En función del rostro"</string> <string name="inline_done_button" msgid="6043094985588909584">"Listo"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificaciones"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silenciada"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar la pantalla dividida con la app a la derecha"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar la pantalla dividida con la app a la izquierda"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar la pantalla completa"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar renderización en ventanas para computadoras de escritorio"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ubicar la app a la derecha o abajo cuando usas la pantalla dividida"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ubicar la app a la izquierda o arriba cuando usas la pantalla dividida"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante pantalla dividida: Reemplaza una app con otra"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"No se puede ocultar la sesión multimedia actual."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml index 91f5f886bc9b..3310d2bc0fb0 100644 --- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desactivado"</item> <item msgid="4875147066469902392">"Activado"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"No disponible"</item> <item msgid="5044688398303285224">"Desactivada"</item> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 7902db813708..ecd3fdab13aa 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Alrededores"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Derecha"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Entorno"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Entorno izquierdo"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Entorno derecho"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expandir a los controles separados de izquierda y derecha"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer al control unificado"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar alrededores"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Dejar de silenciar alrededores"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos automáticos"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ajustes"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string> @@ -517,7 +513,7 @@ <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Desliza hacia la izquierda para iniciar el tutorial de la comunidad"</string> <string name="cta_tile_button_to_open_widget_editor" msgid="3871562362382963878">"Personalizar"</string> <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Cerrar"</string> - <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Añade, elimina y reordena tus widgets en este espacio"</string> + <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Añade, elimina y reordena tus widgets"</string> <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Añade más widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activado: basado en caras"</string> <string name="inline_done_button" msgid="6043094985588909584">"Hecho"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificaciones"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silencio"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminado"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar la pantalla dividida con la aplicación a la derecha"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar la pantalla dividida con la aplicación a la izquierda"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar pantalla completa"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar el escritorio basado en ventanas"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar a la aplicación de la derecha o de abajo en pantalla dividida"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar a la app de la izquierda o de arriba en pantalla dividida"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Con pantalla dividida: reemplazar una aplicación por otra"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Añadir a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición no válida."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tarjeta ya añadida"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Recuadro añadido"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Recuadro quitado"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de ajustes rápidos."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"La sesión multimedia no se puede ocultar."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml index c5b6c2e7d994..546190fc7702 100644 --- a/packages/SystemUI/res/values-es/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desactivado"</item> <item msgid="4875147066469902392">"Activado"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"No disponible"</item> <item msgid="5044688398303285224">"Desactivado"</item> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 723a3eb1f401..2928c96b9689 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ümbritsevad helid"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasakule"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Paremale"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ümbritsevad helid"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Vasak ümbrus"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Parem ümbrus"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Vasaku ja parema poole eraldi juhtimine"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Mõlema poole ühtne juhtimine"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ümbritsevate helide vaigistamine"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ümbritsevate helide vaigistuse tühistamine"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tööriistad"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Reaalajas subtiitrid"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Seaded"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Märkus"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Sees – näopõhine"</string> <string name="inline_done_button" msgid="6043094985588909584">"Valmis"</string> <string name="inline_ok_button" msgid="603075490581280343">"Rakenda"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Lülita märguanded välja"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Hääletu"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Vaikeseade"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automaatne"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Jagatud ekraanikuva kasutamine, rakendus kuvatakse paremal"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Jagatud ekraanikuva kasutamine, rakendus kuvatakse vasakul"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Lülita täisekraanile"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Kasuta töölaua aknaid"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Paremale või alumisele rakendusele lülitamine jagatud ekraani ajal"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vasakule või ülemisele rakendusele lülitamine jagatud ekraani ajal"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekraanikuva jagamise ajal: ühe rakenduse asendamine teisega"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Sobimatu asukoht."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Asend <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Paan on juba lisatud"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Paan on lisatud"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Paan on eemaldatud"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kiirseadete redigeerija."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita see rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> meediajuhik?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Praegust meediaseanssi ei saa peita."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> esitatakse rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml index e9949bf5726a..1defe925cf75 100644 --- a/packages/SystemUI/res/values-et/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Väljas"</item> <item msgid="4875147066469902392">"Sees"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Pole saadaval"</item> <item msgid="5044688398303285224">"Väljas"</item> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 55b223ae5ac1..99dec017c0f4 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ingurunea"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ezkerrekoa"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Eskuinekoa"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ingurunea"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ezkerreko ingurunea"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Eskuineko ingurunea"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Zabaldu ezkerreko eta eskuineko kontrolatzeko aukerak bereiz erabiltzeko"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Tolestu kontrolatzeko aukerak bateratuta erabiltzeko"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Desaktibatu ingurunearen audioa"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Aktibatu ingurunearen audioa"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tresnak"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Istanteko azpitituluak"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ezarpenak"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Oharra"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktibatuta: aurpegian oinarrituta"</string> <string name="inline_done_button" msgid="6043094985588909584">"Eginda"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplikatu"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desaktibatu jakinarazpenak"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Isila"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Lehenetsia"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikoa"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Erabili pantaila zatitua eta ezarri aplikazio hau eskuinean"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Erabili pantaila zatitua eta ezarri aplikazio hau ezkerrean"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Erabili pantaila osoa"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Erabili ordenagailuan leihoak erabiltzeko modua"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Aldatu eskuineko edo beheko aplikaziora pantaila zatitua erabiltzean"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Aldatu ezkerreko edo goiko aplikaziora pantaila zatitua erabiltzean"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Pantaila zatituan zaudela, ordeztu aplikazio bat beste batekin"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Gehitu <xliff:g id="POSITION">%1$d</xliff:g>garren lekuan"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kokapenak ez du balio."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>garren lekua"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Lauza gehituta dago jada"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Gehitu da lauza"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kendu da lauza"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ezarpen bizkorren editorea."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Multimedia kontrolatzeko aukerak (<xliff:g id="APP_NAME">%1$s</xliff:g>) ezkutatu?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Ezin da ezkutatu multimedia-saioa."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) ari da erreproduzitzen <xliff:g id="APP_LABEL">%3$s</xliff:g> bidez"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> @@ -1576,6 +1570,5 @@ <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ezezagunak"</string> <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Lauza guztiak berrezarri nahi dituzu?"</string> <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Gailuaren jatorrizko ezarpenak berrezarriko dira ezarpen bizkorren lauza guztietan"</string> - <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) --> - <skip /> + <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string> </resources> diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml index e47b658d0fae..923d84f23025 100644 --- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desaktibatuta"</item> <item msgid="4875147066469902392">"Aktibatuta"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Ez dago erabilgarri"</item> <item msgid="5044688398303285224">"Desaktibatuta"</item> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index c28ec975e931..db76009629c4 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"پیرامون"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"چپ"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"راست"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"پیرامون"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"پیرامون چپ"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"پیرامون راست"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ازهم بازکردن برای کنترلهای جداگانه چپ و راست"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"جمع کردن برای کنترل یکپارچه"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"بیصدا کردن پیرامون"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"صدادار کردن پیرامون"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ابزارها"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس زنده ناشنوایان"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"تنظیمات"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"یادداشت"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"روشن - براساس چهره"</string> <string name="inline_done_button" msgid="6043094985588909584">"تمام"</string> <string name="inline_ok_button" msgid="603075490581280343">"اعمال"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"خاموش کردن اعلانها"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"بیصدا"</string> <string name="notification_alert_title" msgid="3656229781017543655">"پیشفرض"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"استفاده از صفحهٔ دونیمه با قرار گرفتن برنامه در سمت راست"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"استفاده از صفحهٔ دونیمه با قرار گرفتن برنامه در سمت چپ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"استفاده از حالت تمامصفحه"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"استفاده از پردازش پنجرهای رایانه"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"رفتن به برنامه سمت راست یا پایین درحین استفاده از صفحهٔ دونیمه"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"رفتن به برنامه سمت چپ یا بالا درحین استفاده از صفحهٔ دونیمه"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"درحین صفحهٔ دونیمه: برنامهای را با دیگری جابهجا میکند"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"این کنترل رسانه برای <xliff:g id="APP_NAME">%1$s</xliff:g> پنهان شود؟"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"جلسه رسانه کنونی نمیتواند پنهان شود."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"پنهان کردن"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش میشود"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml index 1025f3d0812a..ee9429402779 100644 --- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"خاموش"</item> <item msgid="4875147066469902392">"روشن"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"دردسترس نیست"</item> <item msgid="5044688398303285224">"خاموش"</item> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 98f4883fe880..8df9aeb04f92 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -425,20 +425,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ympäristö"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasen"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Oikea"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ympäristö"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ympäristö vasemmalla"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ympäristö oikealla"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Laajenna vasemmalle ja oikealle erilliset ohjaimet"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Tiivistä yhtenäiseksi säätimeksi"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mykistä ympäristö"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Poista ympäristön mykistys"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Työkalut"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstitys"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Asetukset"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Muistiinpano"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string> @@ -800,7 +796,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Päällä – kasvojen perusteella"</string> <string name="inline_done_button" msgid="6043094985588909584">"Valmis"</string> <string name="inline_ok_button" msgid="603075490581280343">"Käytä"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Poista ilmoitukset käytöstä"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Äänetön"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Oletus"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automaattinen"</string> @@ -911,8 +908,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Käytä jaettua näyttöä niin, että sovellus on oikealla"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Käytä jaettua näyttöä niin, että sovellus on vasemmalla"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Käytä koko näytön tilaa"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Käytä työpöydän ikkunointia"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Vaihda sovellukseen oikealla tai alapuolella jaetussa näytössä"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vaihda sovellukseen vasemmalla tai yläpuolella jaetussa näytössä"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Jaetun näytön aikana: korvaa sovellus toisella"</string> @@ -1008,8 +1004,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisää paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Virheellinen sijainti."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Laatta on jo lisätty"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kiekko lisätty"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kiekko poistettu"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Pika-asetusten muokkausnäkymä"</string> @@ -1210,7 +1205,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Piilotetaanko mediaohjain (<xliff:g id="APP_NAME">%1$s</xliff:g>)?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Tätä median käyttökertaa ei voi piilottaa."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Piilota"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> soittaa nyt tätä: <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml index 5452f2630668..76a77ad058ef 100644 --- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Poissa päältä"</item> <item msgid="4875147066469902392">"Päällä"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Ei saatavilla"</item> <item msgid="5044688398303285224">"Poissa päältä"</item> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 95adcd3e05a4..9bd16d975d74 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Environnement"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Droit"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Environnement"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Environnement à gauche"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Environnement à droite"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Développer les commandes distinctes à gauche et à droite"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Passer au contrôle unifié"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ignorer les sons de l\'environnement"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Réactiver les sons de l\'environnement"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Paramètres"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activé : en fonction du visage"</string> <string name="inline_done_button" msgid="6043094985588909584">"Terminé"</string> <string name="inline_ok_button" msgid="603075490581280343">"Appliquer"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Désactiver les notifications"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Mode silencieux"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utiliser l\'Écran divisé avec l\'appli à droite"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utiliser l\'Écran divisé avec l\'appli à gauche"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utiliser le mode plein écran"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Utiliser le fenêtrage du bureau"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'Écran divisé"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'appli à gauche ou au-dessus avec l\'Écran divisé"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une appli par une autre"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Masquer ce contrôleur de contenu multimédia pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Impossible de masquer la session multimédia actuelle"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecteur à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml index 487c566bf50f..01f33917a979 100644 --- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Désactivée"</item> <item msgid="4875147066469902392">"Activé"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Non disponible"</item> <item msgid="5044688398303285224">"Désactivée"</item> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 04c147cdd5a7..63ac0cab4b17 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sons environnants"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Droite"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Sons environnants"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Environnement à gauche"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Environnement à droite"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Développer les commandes gauche et droite"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Réduire en une commande unifiée"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Couper le mode Sons environnants"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Réactiver le mode Sons environnants"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Paramètres"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Active - En fonction du visage"</string> <string name="inline_done_button" msgid="6043094985588909584">"OK"</string> <string name="inline_ok_button" msgid="603075490581280343">"Appliquer"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Désactiver les notifications"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silencieux"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utiliser l\'écran partagé avec l\'appli sur la droite"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utiliser l\'écran partagé avec l\'appli sur la gauche"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utiliser le mode plein écran"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Utiliser le fenêtrage de l\'ordinateur"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'écran partagé"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passez à l\'appli à gauche ou au-dessus avec l\'écran partagé"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Emplacement non valide."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"La carte a déjà été ajoutée"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloc ajouté"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloc supprimé"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur Réglages rapides"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Masquer cette commande multimédia pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Session multimédia en cours impossible à masquer."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecture depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sur <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml index 52c7c0c09fd7..620e46c88cd5 100644 --- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Désactivé"</item> <item msgid="4875147066469902392">"Activé"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Indisponible"</item> <item msgid="5044688398303285224">"Désactivé"</item> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 6ab779a2569c..80da559ba1c5 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerdo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dereito"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ambiente"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambiente á esquerda"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambiente á dereita"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Despregar para controis separados do lado esquerdo e do dereito"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer para control unificado"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar o ambiente"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Activar o son ambiental"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos instantáneos"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configuración"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Queres desbloquear a cámara do dispositivo?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activada: baseada na cara"</string> <string name="inline_done_button" msgid="6043094985588909584">"Feito"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificacións"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silenciadas"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Configuración predeterminada"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar pantalla dividida coa aplicación na dereita"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar pantalla dividida coa aplicación na esquerda"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar a pantalla completa"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar as ventás do ordenador"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar á aplicación da dereita ou de abaixo coa pantalla dividida"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar á aplicación da esquerda ou de arriba coa pantalla dividida"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"En modo de pantalla dividida: Substituír unha aplicación por outra"</string> @@ -997,17 +993,16 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconas das notificacións que teñan baixa prioridade"</string> <string name="other" msgid="429768510980739978">"Outros"</string> - <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"activar/desactivar o tamaño do recadro"</string> - <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar tarxeta"</string> + <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"cambiar o tamaño do atallo"</string> + <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar atallo"</string> <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"engadir o atallo á última posición"</string> - <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover tarxeta"</string> + <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover atallo"</string> <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Engadir o atallo á última posición"</string> <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engadir á posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición non válida."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Atallo xa engadido"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Engadiuse a tarxeta"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Quitouse a tarxeta"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuración rápida."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Queres ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Non se pode ocultar esta sesión multimedia."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Estase reproducindo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml index 7cf5f8295fe8..ca19e0ecd24d 100644 --- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Non"</item> <item msgid="4875147066469902392">"Si"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Non dispoñible"</item> <item msgid="5044688398303285224">"Non"</item> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index a0dbf73fa73f..17bcdf091f9e 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -426,20 +426,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"આસપાસના અવાજો"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ડાબે"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"જમણે"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"આસપાસના અવાજો"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ડાબી તરફથી આવતા અવાજો"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"જમણી તરફથી આવતા અવાજો"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ડાબે અને જમણે અલગ કરેલા નિયંત્રણો સુધી વિસ્તૃત કરો"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"એકીકૃત નિયંત્રણ સુધી નાનું કરો"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"આસપાસના અવાજો મ્યૂટ કરો"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"આસપાસના અવાજો અનમ્યૂટ કરો"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ટૂલ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"લાઇવ કૅપ્શન"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"સેટિંગ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"નોંધ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ડિવાઇસના માઇક્રોફોનને અનબ્લૉક કરીએ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ડિવાઇસના કૅમેરાને અનબ્લૉક કરીએ?"</string> @@ -801,7 +797,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ચાલુ છે - ચહેરા આધારિત રોટેશન"</string> <string name="inline_done_button" msgid="6043094985588909584">"થઈ ગયું"</string> <string name="inline_ok_button" msgid="603075490581280343">"લાગુ કરો"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"નોટિફિકેશન બંધ કરો"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"સાઇલન્ટ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ડિફૉલ્ટ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ઑટોમૅટિક રીતે"</string> @@ -912,8 +909,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"હાલની ઍપને જમણી બાજુએ રાખીને વિભાજિત સ્ક્રીનનો ઉપયોગ કરો"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"હાલની ઍપને ડાબી બાજુએ રાખીને વિભાજિત સ્ક્રીનનો ઉપયોગ કરો"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"પૂર્ણ સ્ક્રીનનો ઉપયોગ કરો"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ડેસ્કટૉપ વિન્ડોઇંગનો ઉપયોગ કરો"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે જમણી બાજુ કે નીચેની ઍપ પર સ્વિચ કરો"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે ડાબી બાજુની કે ઉપરની ઍપ પર સ્વિચ કરો"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"વિભાજિત સ્ક્રીન દરમિયાન: એક ઍપને બીજી ઍપમાં બદલો"</string> @@ -1009,8 +1005,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"જગ્યા પર <xliff:g id="POSITION">%1$d</xliff:g> ઉમેરો"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"સ્થિતિ અમાન્ય છે."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"જગ્યા <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ટાઇલ પહેલેથી ઉમેરેલી છે"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ટાઇલ ઉમેરી"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ટાઇલ કાઢી નાખી"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ એડિટર."</string> @@ -1211,7 +1206,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"શું <xliff:g id="APP_NAME">%1$s</xliff:g> માટે મીડિયાના નિયંત્રણો છુપાવીએ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"હાલનું મીડિયા સત્ર છુપાવી શકાતું નથી."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"છુપાવો"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>માંથી <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml index a003106597c5..759e43664379 100644 --- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"બંધ છે"</item> <item msgid="4875147066469902392">"ચાલુ છે"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ઉપલબ્ધ નથી"</item> <item msgid="5044688398303285224">"બંધ છે"</item> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 0b8666115cb6..f4c05ba2f8c5 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"आस-पास का वॉल्यूम"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बाईं ओर के वॉल्यूम के लिए"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"दाईं ओर के वॉल्यूम के लिए"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"आस-पास का वॉल्यूम"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"बाईं ओर का वॉल्यूम"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"दाईं ओर का वॉल्यूम"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"दाईं और बाईं ओर के वॉल्यूम को अलग-अलग मैनेज करने के लिए, वॉल्यूम पैनल को बड़ा करें"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"यूनिफ़ाइड कंट्रोल पर जाने के लिए पैनल को छोटा करें"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"आस-पास के वॉल्यूम को म्यूट करें"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"आस-पास के वॉल्यूम को अनम्यूट करें"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव कैप्शन"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"सेटिंग"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"क्या आपको माइक्रोफ़ोन का ऐक्सेस अनब्लॉक करना है?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"क्या आपको कैमरे का ऐक्सेस अनब्लॉक करना है?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"चालू है - चेहरे की गतिविधि के हिसाब से कैमरे को घुमाने की सुविधा"</string> <string name="inline_done_button" msgid="6043094985588909584">"हो गया"</string> <string name="inline_ok_button" msgid="603075490581280343">"लागू करें"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचनाएं बंद करें"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"बिना आवाज़ के सूचनाएं दिखाएं"</string> <string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"स्प्लिट स्क्रीन की सुविधा चालू करें और इस ऐप्लिकेशन को दाईं ओर दिखाएं"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"स्प्लिट स्क्रीन की सुविधा चालू करें और इस ऐप्लिकेशन को बाईं ओर दिखाएं"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"फ़ुल स्क्रीन मोड का इस्तेमाल करें"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"डेस्कटॉप विंडोविंग का इस्तेमाल करें"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन पर, दाईं ओर या नीचे के ऐप पर स्विच करने के लिए"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन पर, बाईं ओर या ऊपर के ऐप पर स्विच करने के लिए"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीन के दौरान: एक ऐप्लिकेशन को दूसरे ऐप्लिकेशन से बदलें"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर जोड़ें"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"मौजूदा जगह अमान्य है."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"टाइल की पोज़िशन <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"टाइल पहले से जोड़ा गया है"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोड़ी गई"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाई गई"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"त्वरित सेटिंग संपादक."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"क्या <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए, इस मीडिया कंट्रोल को छिपाना है?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"मौजूदा मीडिया सेशन को छिपाया नहीं जा सकता."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"छिपाएं"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चल रहा है"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> में से <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml index ae0831651607..410f25db0900 100644 --- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"बंद है"</item> <item msgid="4875147066469902392">"चालू है"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"उपलब्ध नहीं है"</item> <item msgid="5044688398303285224">"बंद है"</item> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 608b498d2100..9d2509404a8c 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okruženje"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Okruženje s lijeve strane"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Okruženje s desne strane"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširi u zasebne kontrole slijeva i zdesna"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sažmi u objedinjenu kontrolu"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključi zvuk okruženja"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Uključi zvuk okruženja"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Postavke"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Napomena"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati kameru uređaja?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na temelju lica"</string> <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string> <string name="inline_ok_button" msgid="603075490581280343">"Primijeni"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obavijesti"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Bešumno"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Upotreba podijeljenog zaslona s aplikacijom s desne strane"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Upotreba podijeljenog zaslona s aplikacijom s lijeve strane"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Upotreba prikaza na cijelom zaslonu"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Upotreba prikaza u prozorima na računalu"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak na aplikaciju zdesna ili ispod uz podijeljeni zaslon"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prelazak na aplikaciju slijeva ili iznad uz podijeljeni zaslon"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijekom podijeljenog zaslona: zamijeni aplikaciju drugom"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Položaj nije važeći."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Pločica je već dodana"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač brzih postavki."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li sakriti kontroler medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutačna medijska sesija ne može se sakriti."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> reproducira se putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml index 51b667c3fafd..bbfcf840e53f 100644 --- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Isključeno"</item> <item msgid="4875147066469902392">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nedostupno"</item> <item msgid="5044688398303285224">"Isključeno"</item> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 36187b97d70b..bdeececfd9ae 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Környezet"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Bal"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Jobb"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Környezet"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Bal oldali környezet"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Jobb oldali környezet"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Kibontás a balra és jobbra elválasztott vezérlőkhöz"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Összecsukás az egységes vezérléshez"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Környezet némítása"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Környezet némításának feloldása"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eszközök"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Élő feliratozás"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Beállítások"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Megjegyzés"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Be: Arcalapú"</string> <string name="inline_done_button" msgid="6043094985588909584">"Kész"</string> <string name="inline_ok_button" msgid="603075490581280343">"Alkalmaz"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Az értesítések kikapcsolása"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Néma"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Alapértelmezett"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikus"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Osztott képernyő használata, az alkalmazás a jobb oldalon van"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Osztott képernyő használata, az alkalmazás a bal oldalon van"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Teljes képernyő használata"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Asztali ablakkezelési mód használata"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Váltás a jobb oldalt, illetve lent lévő appra osztott képernyő esetén"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Váltás a bal oldalt, illetve fent lévő appra osztott képernyő esetén"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Osztott képernyőn: az egyik alkalmazás lecserélése egy másikra"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Elrejti ezt a(z) <xliff:g id="APP_NAME">%1$s</xliff:g>-médiavezérlőt?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Az aktuális média-munkamenet nem rejthető el."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Elrejtés"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című száma hallható itt: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml index c8f7b0f2fef8..8bd57214a28d 100644 --- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Ki"</item> <item msgid="4875147066469902392">"Be"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nem áll rendelkezésre"</item> <item msgid="5044688398303285224">"Ki"</item> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 6a7543f754fd..d448486faf64 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Միացնել շրջակայքի ձայները"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Գործիքներ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Կենդանի ենթագրեր"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Կարգավորումներ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Նշում"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Արգելահանե՞լ սարքի խոսափողը"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Արգելահանե՞լ սարքի տեսախցիկը"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Միաց․ – Դիմաճանաչման հիման վրա"</string> <string name="inline_done_button" msgid="6043094985588909584">"Փակել"</string> <string name="inline_ok_button" msgid="603075490581280343">"Կիրառել"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Անջատել ծանուցումները"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Անձայն"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Կանխադրված"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Ավտոմատ"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Տրոհել էկրանը և տեղավորել այս հավելվածը աջ կողմում"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Տրոհել էկրանը և տեղավորել այս հավելվածը ձախ կողմում"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Օգտագործեք լիաէկրան ռեժիմը"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Օգտագործել համակարգչի պատուհանի ռեժիմը"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Անցեք աջ կողմի կամ ներքևի հավելվածին տրոհված էկրանի միջոցով"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Անցեք աջ կողմի կամ վերևի հավելվածին տրոհված էկրանի միջոցով"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Տրոհված էկրանի ռեժիմում մեկ հավելվածը փոխարինել մյուսով"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Թաքցնե՞լ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի մեդիա աշխատաշրջանի կառավարման տարրը։"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Չհաջողվեց թաքցնել ընթացիկ մուլտիմեդիա աշխատաշրջանը։"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Թաքցնել"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Այժմ նվագարկվում է <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>՝ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ից"</string> diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml index e7eee796f91d..3497c404600b 100644 --- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Անջատված է"</item> <item msgid="4875147066469902392">"Միացված է"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Հասանելի չէ"</item> <item msgid="5044688398303285224">"Անջատված է"</item> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index c09e03c428d2..5867bf7c5cc6 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Suara sekitar"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Suara sekitar"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Suara sekitar kiri"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Suara sekitar kanan"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Luaskan ke kontrol terpisah kiri dan kanan"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Ciutkan ke kontrol terpadu"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Bisukan suara sekitar"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Bunyikan suara sekitar"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alat"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Teks Otomatis"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Setelan"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Catatan"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Berhenti memblokir mikrofon perangkat?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Berhenti memblokir kamera perangkat?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktif - Berbasis deteksi wajah"</string> <string name="inline_done_button" msgid="6043094985588909584">"Selesai"</string> <string name="inline_ok_button" msgid="603075490581280343">"Terapkan"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Nonaktifkan notifikasi"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatis"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gunakan layar terpisah dengan aplikasi di sebelah kanan"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gunakan layar terpisah dengan aplikasi di sebelah kiri"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gunakan layar penuh"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gunakan mode jendela desktop"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Beralih ke aplikasi di bagian kanan atau bawah saat menggunakan layar terpisah"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Beralih ke aplikasi di bagian kiri atau atas saat menggunakan layar terpisah"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Dalam layar terpisah: ganti salah satu aplikasi dengan yang lain"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan ke posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisi tidak valid."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kartu telah ditambahkan"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartu ditambahkan"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartu dihapus"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor setelan cepat."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kontrol media untuk <xliff:g id="APP_NAME">%1$s</xliff:g> ini?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media aktif tidak dapat disembunyikan."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Setelan"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sedang diputar dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> dari <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml index 182924dff630..7df0b0d9f34c 100644 --- a/packages/SystemUI/res/values-in/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Nonaktif"</item> <item msgid="4875147066469902392">"Aktif"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Tidak tersedia"</item> <item msgid="5044688398303285224">"Mati"</item> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index b853a5561c4c..f949400bf09d 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Kveikja á hljóði umhverfis"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verkfæri"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Skjátextar í rauntíma"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Stillingar"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Glósa"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Kveikt – út frá andliti"</string> <string name="inline_done_button" msgid="6043094985588909584">"Lokið"</string> <string name="inline_ok_button" msgid="603075490581280343">"Nota"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Slökkva á tilkynningum"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Hljóðlaust"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Sjálfgefið"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Sjálfvirk"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Notaðu skjáskiptingu fyrir forritið til hægri"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Notaðu skjáskiptingu fyrir forritið til vinstri"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Nota allan skjáinn"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Nota gluggastillingu í tölvu"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skiptu í forrit til hægri eða fyrir neðan þegar skjáskipting er notuð"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skiptu í forrit til vinstri eða fyrir ofan þegar skjáskipting er notuð"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Fela þessa efnisstýringu fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Ekki tókst að fela opna efnislotu."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fela"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> er í spilun á <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml index 58ce0ae7c443..d1b04e05ad7f 100644 --- a/packages/SystemUI/res/values-is/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Slökkt"</item> <item msgid="4875147066469902392">"Kveikt"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Ekki í boði"</item> <item msgid="5044688398303285224">"Slökkt"</item> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index ceb1ca1c5cb4..708fa78bedff 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -138,7 +138,7 @@ <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Interrompi registrazione"</string> <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Condivisione dello schermo in corso"</string> <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Condivisione di contenuti in corso…"</string> - <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vuoi interrompere la condivisione dello schermo?"</string> + <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Interrompere la condivisione dello schermo?"</string> <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Interrompere la condivisione?"</string> <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Al momento stai condividendo l\'intero schermo con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string> <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Al momento stai condividendo l\'intero schermo con un\'app"</string> @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Riattiva audio ambientale"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Strumenti"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sottotitoli in tempo reale"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Impostazioni"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vuoi sbloccare il microfono del dispositivo?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vuoi sbloccare la fotocamera del dispositivo?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On - Rotazione basata sul viso"</string> <string name="inline_done_button" msgid="6043094985588909584">"Fine"</string> <string name="inline_ok_button" msgid="603075490581280343">"Applica"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Disattiva notifiche"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Modalità silenziosa"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Modalità predefinita"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatico"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utilizza lo schermo diviso con l\'app a destra"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utilizza lo schermo diviso con l\'app a sinistra"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utilizza la modalità a schermo intero"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usa windowing del desktop"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passa all\'app a destra o sotto mentre usi lo schermo diviso"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passa all\'app a sinistra o sopra mentre usi lo schermo diviso"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Nascondere questo controllo multimediale per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Imposs. nascondere sessione multimediale corrente."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Nascondi"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> è in riproduzione da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> di <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml index 5c56d085652f..afbd3d9b1910 100644 --- a/packages/SystemUI/res/values-it/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Off"</item> <item msgid="4875147066469902392">"On"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Non disponibile"</item> <item msgid="5044688398303285224">"Off"</item> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 8123c7e2ea38..35500fbc4107 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"הרעשים בסביבה"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"שמאל"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ימין"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"הרעשים בסביבה"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"הרעשים בסביבה בצד שמאל"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"הרעשים בסביבה בצד ימין"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"הרחבה לאמצעי בקרה נפרדים לצד שמאל ולצד ימין"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"כיווץ לאמצעי בקרה מאוחד"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"השתקת הרעשים בסביבה"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ביטול השתקת הרעשים בסביבה"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"כלים"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"כתוביות מיידיות"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"הגדרות"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"פתק"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"לבטל את חסימת המיקרופון של המכשיר?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"לבטל את חסימת המצלמה של המכשיר?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"פועל – מבוסס על זיהוי פנים"</string> <string name="inline_done_button" msgid="6043094985588909584">"סיום"</string> <string name="inline_ok_button" msgid="603075490581280343">"אישור"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"השבתת ההתראות"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"שקט"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ברירת מחדל"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"באופן אוטומטי"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"שימוש במסך מפוצל כשהאפליקציה בצד ימין"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"שימוש במסך מפוצל כשהאפליקציה בצד שמאל"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"שימוש במסך מלא"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"עיבוד החלק הנצפה בלבד במחשב"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"מעבר לאפליקציה משמאל או למטה בזמן שימוש במסך מפוצל"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"מעבר לאפליקציה מימין או למעלה בזמן שימוש במסך מפוצל"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"הוספה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"המיקום לא תקין."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"כרטיס המידע כבר נוסף"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"הלחצן נוסף"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"הלחצן הוסר"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"עורך הגדרות מהירות."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"להסתיר את בקר המדיה הזה לאפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"לא ניתן להסתיר את סשן המדיה הנוכחי."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"הסתרה"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מופעל מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> מתוך <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml index d1bd612a0e0f..42aa531186f6 100644 --- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"כבוי"</item> <item msgid="4875147066469902392">"פועל"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"לא זמין"</item> <item msgid="5044688398303285224">"כבוי"</item> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 2fc703c44ca2..fc792b6f9850 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ON - 顔ベース"</string> <string name="inline_done_button" msgid="6043094985588909584">"完了"</string> <string name="inline_ok_button" msgid="603075490581280343">"適用"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"通知を OFF にする"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"サイレント"</string> <string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"分割画面の使用(アプリを右側に表示)"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"分割画面の使用(アプリを左側に表示)"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"全画面表示に切り替える"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"デスクトップ ウィンドウを使用する"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"分割画面の使用時に右側または下部のアプリに切り替える"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"分割画面の使用時に左側または上部のアプリに切り替える"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"分割画面中: アプリを順に置換する"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> のこのコントロールを非表示にしますか?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"現在のメディア セッションは非表示にできません。"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"再開"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)が <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生中"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml index cce5ceb7945d..4827ad38dfa7 100644 --- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"OFF"</item> <item msgid="4875147066469902392">"ON"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"使用不可"</item> <item msgid="5044688398303285224">"OFF"</item> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 86f8e33b2d76..e13a1b3a3bd8 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ჩართული — სახის მიხედვით"</string> <string name="inline_done_button" msgid="6043094985588909584">"მზადაა"</string> <string name="inline_ok_button" msgid="603075490581280343">"მისადაგება"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"შეტყობინებების გამორთვა"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ჩუმი"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ნაგულისხმევი"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ავტომატური"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ეკრანის გაყოფის გამოყენება აპზე მარჯვნივ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ეკრანის გაყოფის გამოყენება აპზე მარცხნივ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"სრული ეკრანის გამოყენება"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"დესკტოპის ფანჯრის რეჟიმის გამოყენება"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ეკრანის გაყოფის გამოყენებისას აპზე მარჯვნივ ან ქვემოთ გადართვა"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ეკრანის გაყოფის გამოყენებისას აპზე მარცხნივ ან ზემოთ გადართვა"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"დაიმალოს მედიის ეს კონტროლერი <xliff:g id="APP_NAME">%1$s</xliff:g> აპში?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"მედიის მიმდინარე სესიის დამალვა შეუძლებელია."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"დამალვა"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"გაგრძელება"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, უკრავს <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-დან <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml index 7a2298143e4c..ebf28c89587b 100644 --- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"გამორთულია"</item> <item msgid="4875147066469902392">"ჩართულია"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"მიუწვდომელია"</item> <item msgid="5044688398303285224">"გამორთულია"</item> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 1a7532b938d7..5fc8b47869b7 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айнала"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол жақ"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Оң жақ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Қоршаған дыбыстар"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Сол жақтағы дыбыстар"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Оң жақтағы дыбыстар"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Сол жақ және оң жақ бөлек бақылау құралдарына жаю"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Біріктірілген бақылау құралына жию"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Айналаның дыбысын өшіру"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Айналаның дыбысын қосу"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Құралдар"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Параметрлер"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ескертпе"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Құрылғы микрофонын блоктан шығару керек пе?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Құрылғы камерасын блоктан шығару керек пе?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Қосулы – бет негізінде"</string> <string name="inline_done_button" msgid="6043094985588909584">"Дайын"</string> <string name="inline_ok_button" msgid="603075490581280343">"Қолдану"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Хабарландыруларды өшіру"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Үнсіз"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Әдепкі"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматты"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Қолданбаны бөлінген экранның оң жағынан пайдалану"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Қолданбаны бөлінген экранның сол жағынан пайдалану"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Толық экранды пайдалану"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Компьютер терезесін пайдалану"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлінген экранда оң не төмен жақтағы қолданбаға ауысу"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлінген экранда сол не жоғары жақтағы қолданбаға ауысу"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлу кезінде: бір қолданбаны басқасымен алмастыру"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> орнына қосу"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Орын жарамсыз."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> орны"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Бөлшек қосылып қойған."</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Бөлшек қосылды."</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Бөлшек өшірілді."</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Жылдам параметрлер өңдегіші."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін медиа контроллері жасырылсын ба?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Ағымдағы мультимедиа сеансын жасыру мүмкін емес."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жасыру"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әні ойнатылуда."</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml index 2b839c89a6e3..45316aa1391e 100644 --- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Өшірулі"</item> <item msgid="4875147066469902392">"Қосулы"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Қолжетімсіз"</item> <item msgid="5044688398303285224">"Өшірулі"</item> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 43c5c700d206..579c509dd6db 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"មជ្ឈដ្ឋានជុំវិញ"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ឆ្វេង"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ស្ដាំ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"មជ្ឈដ្ឋានជុំវិញ"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"មជ្ឈដ្ឋានជុំវិញខាងឆ្វេង"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"មជ្ឈដ្ឋានជុំវិញខាងស្ដាំ"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ពង្រីកទៅជាការគ្រប់គ្រងខាងឆ្វេង និងខាងស្ដាំដាច់ដោយឡែកពីគ្នា"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"បង្រួមទៅជាការគ្រប់គ្រងដែលបានរួមបញ្ចូលគ្នា"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"បិទសំឡេងមជ្ឈដ្ឋានជុំវិញ"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"បើកសំឡេងមជ្ឈដ្ឋានជុំវិញ"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ឧបករណ៍"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"អក្សររត់ក្នុងពេលជាក់ស្ដែង"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ការកំណត់"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"កំណត់ចំណាំ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ឈប់ទប់ស្កាត់មីក្រូហ្វូនរបស់ឧបករណ៍ឬ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ឈប់ទប់ស្កាត់កាមេរ៉ារបស់ឧបករណ៍ឬ?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"បើក - ផ្អែកលើមុខ"</string> <string name="inline_done_button" msgid="6043094985588909584">"រួចរាល់"</string> <string name="inline_ok_button" msgid="603075490581280343">"ប្រើ"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"បិទការជូនដំណឹង"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ស្ងាត់"</string> <string name="notification_alert_title" msgid="3656229781017543655">"លំនាំដើម"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ស្វ័យប្រវត្តិ"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ប្រើមុខងារបំបែកអេក្រង់ជាមួយកម្មវិធីនៅខាងស្ដាំ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ប្រើមុខងារបំបែកអេក្រង់ជាមួយកម្មវិធីនៅខាងឆ្វេង"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ប្រើអេក្រង់ពេញ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ប្រើមុខងារវិនដូកុំព្យូទ័រ"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ប្ដូរទៅកម្មវិធីនៅខាងស្ដាំ ឬខាងក្រោម ពេលកំពុងប្រើមុខងារបំបែកអេក្រង់"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ប្ដូរទៅកម្មវិធីនៅខាងឆ្វេង ឬខាងលើ ពេលកំពុងប្រើមុខងារបំបែកអេក្រង់"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ក្នុងអំឡុងពេលប្រើមុខងារបំបែកអេក្រង់៖ ជំនួសកម្មវិធីពីមួយទៅមួយទៀត"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"បញ្ចូលទៅទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ទីតាំងគ្មានសុពលភាព។"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"បានបញ្ចូលប្រអប់រួចហើយ"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"បានបញ្ចូលប្រអប់"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"បានផ្លាស់ទីប្រអប់"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"កម្មវិធីកែការកំណត់រហ័ស"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"លាក់ផ្ទាំងគ្រប់គ្រងមេឌៀនេះសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"មិនអាចលាក់វគ្គមេឌៀបច្ចុប្បន្នបានទេ។"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"លាក់"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> កំពុងចាក់ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> នៃ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml index 7085509a596a..ec120089a220 100644 --- a/packages/SystemUI/res/values-km/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"បិទ"</item> <item msgid="4875147066469902392">"បើក"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"មិនមានទេ"</item> <item msgid="5044688398303285224">"បិទ"</item> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 8de5281e0a3f..c84b33baed10 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ಆನ್ ಆಗಿದೆ - ಮುಖ-ಆಧಾರಿತ"</string> <string name="inline_done_button" msgid="6043094985588909584">"ಪೂರ್ಣಗೊಂಡಿದೆ"</string> <string name="inline_ok_button" msgid="603075490581280343">"ಅನ್ವಯಿಸಿ"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ನಿಶ್ಶಬ್ದ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ಡೀಫಾಲ್ಟ್"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ಸ್ವಯಂಚಾಲಿತ"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ಬಲಭಾಗದಲ್ಲಿ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ಎಡಭಾಗದಲ್ಲಿ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ಫುಲ್ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಳಸಿ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ಡೆಸ್ಕ್ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್ ಅನ್ನು ಬಳಸಿ"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್ಗೆ ಬದಲಿಸಿ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್ಗೆ ಬದಲಿಸಿ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್ಗೆ ಬದಲಿಸಿ"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಈ ಮಾಧ್ಯಮ ಕಂಟ್ರೋಲ್ಗಳನ್ನು ಮರೆಮಾಡಬೇಕೆ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ಪ್ರಸ್ತುತ ಮಾಧ್ಯಮ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ಮರೆಮಾಡಿ"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml index 487be133293f..ad57922c9f2c 100644 --- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ಆಫ್"</item> <item msgid="4875147066469902392">"ಆನ್"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ಲಭ್ಯವಿಲ್ಲ"</item> <item msgid="5044688398303285224">"ಆಫ್"</item> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index c3a1a1a63bc5..048050cf53df 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"주변 소리"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"왼쪽"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"오른쪽"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"주변 소리"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"왼쪽 주변 소리"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"오른쪽 주변 소리"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"왼쪽 및 오른쪽 개별 제어로 확장"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"통합 제어로 축소"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"주변 소리 음소거"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"주변 소리 음소거 해제"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"도구"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"실시간 자막"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"설정"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"메모"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"기기 마이크를 차단 해제하시겠습니까?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"기기 카메라를 차단 해제하시겠습니까?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"켜짐 - 얼굴 기준"</string> <string name="inline_done_button" msgid="6043094985588909584">"완료"</string> <string name="inline_ok_button" msgid="603075490581280343">"적용"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"알림 사용 중지"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"무음"</string> <string name="notification_alert_title" msgid="3656229781017543655">"기본값"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"자동"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"앱이 오른쪽에 오도록 화면 분할 사용"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"앱이 왼쪽에 오도록 화면 분할 사용"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"전체 화면 사용"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"데스크톱 창 사용"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"화면 분할을 사용하는 중에 오른쪽 또는 아래쪽에 있는 앱으로 전환"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"화면 분할을 사용하는 중에 왼쪽 또는 위쪽에 있는 앱으로 전환하기"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"화면 분할 중: 다른 앱으로 바꾸기"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> 위치에 추가"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"위치가 잘못되었습니다."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> 위치"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"타일이 이미 추가되어 있음"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"타일 추가됨"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"타일 삭제됨"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"빠른 설정 편집기"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 미디어 컨트롤을 숨길까요?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"현재 미디어 세션은 숨길 수 없습니다."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생 중"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml index dfdcefe0ca0f..49113eea79b7 100644 --- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"꺼짐"</item> <item msgid="4875147066469902392">"켜짐"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"이용 불가"</item> <item msgid="5044688398303285224">"꺼짐"</item> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 23cc8ee23fb6..e6b108126012 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айланадагы үндөр"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Оң"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Айланадагы үндөр"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Сол жактагы үндөр"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Оң жактагы үндөр"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Cол жана оң жактагы өзүнчө башкаруу элементтерине жайып көрсөтүү"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Бирдиктүү башкаруу элементине жыйыштыруу"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Айланадагы үндөрдү басуу"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Айланадагы үндөрдү чыгаруу"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Куралдар"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ыкчам коштомо жазуулар"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Параметрлер"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Учкай маалымат"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Түзмөктүн микрофонун бөгөттөн чыгарасызбы?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Түзмөктүн камерасын бөгөттөн чыгарасызбы?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Күйүк – Жүздүн негизинде"</string> <string name="inline_done_button" msgid="6043094985588909584">"Бүттү"</string> <string name="inline_ok_button" msgid="603075490581280343">"Колдонуу"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Билдирмелерди өчүрүү"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Үнсүз"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Демейки"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматтык"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Колдонмону оңго жылдырып, экранды бөлүү"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Колдонмону солго жылдырып, экранды бөлүү"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Толук экранды колдонуу"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Иш тактанын терезелерин колдонуу"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлүнгөн экранда сол же төмөн жактагы колдонмого которулуу"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлүнгөн экранды колдонуп жатканда сол же жогору жактагы колдонмого которулуңуз"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлүү режиминде бир колдонмону экинчисине алмаштыруу"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> \'да ушул медиа башкарууну жашырасызбы?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Учурдагы медиа сеансын жашыруу мүмкүн эмес."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ыры (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотулуп жатат"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ичинен <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml index 6077f6647ca9..68f8987a02dc 100644 --- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Өчүк"</item> <item msgid="4875147066469902392">"Күйүк"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Жеткиликсиз"</item> <item msgid="5044688398303285224">"Өчүк"</item> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 69b79b89cb80..e7229e8f3704 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ເຊົາປິດສຽງແວດລ້ອມ"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ເຄື່ອງມື"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ຄຳບັນຍາຍສົດ"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ການຕັ້ງຄ່າ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"ບັນທຶກ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ປົດບລັອກໄມໂຄຣໂຟນອຸປະກອນບໍ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ປົດບລັອກກ້ອງຖ່າຍຮູບອຸປະກອນບໍ?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ເປີດ - ອ້າງອີງໃບໜ້າ"</string> <string name="inline_done_button" msgid="6043094985588909584">"ແລ້ວໆ"</string> <string name="inline_ok_button" msgid="603075490581280343">"ນຳໃຊ້"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ປິດການແຈ້ງເຕືອນ"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ປິດສຽງ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ຄ່າເລີ່ມຕົ້ນ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ອັດຕະໂນມັດ"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ໃຊ້ໂໝດແບ່ງໜ້າຈໍໂດຍໃຫ້ແອັບຢູ່ເບື້ອງຂວາ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ໃຊ້ໂໝດແບ່ງໜ້າຈໍໂດຍໃຫ້ແອັບຢູ່ເບື້ອງຊ້າຍ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ໃຊ້ແບບເຕັມຈໍ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ໃຊ້ໜ້າຈໍເດັສທັອບ"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຂວາ ຫຼື ທາງລຸ່ມໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຊ້າຍ ຫຼື ທາງເທິງໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ໃຫ້ປ່ຽນຈາກແອັບໜຶ່ງເປັນອີກແອັບໜຶ່ງ"</string> @@ -1003,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ເພີ່ມໃສ່ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ຕຳແໜ່ງບໍ່ຖືກຕ້ອງ."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ເພີ່ມແຜ່ນແລ້ວ"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ເພີ່ມແຜ່ນແລ້ວ"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ລຶບແຜ່ນແລ້ວ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string> @@ -1205,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"ເຊື່ອງຕົວຄວບຄຸມມີເດຍນີ້ສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ບໍ່ສາມາດເຊື່ອງເຊດຊັນມີເດຍປັດຈຸບັນໄດ້."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ເຊື່ອງ"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ກຳລັງຫຼິ້ນຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ຈາກ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml index 294d6af2b863..90390e23162b 100644 --- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ປິດ"</item> <item msgid="4875147066469902392">"ເປີດ"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ບໍ່ສາມາດໃຊ້ໄດ້"</item> <item msgid="5044688398303285224">"ປິດ"</item> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 1ed102d9869b..6563cb97f35d 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Įjungta – pagal veidą"</string> <string name="inline_done_button" msgid="6043094985588909584">"Atlikta"</string> <string name="inline_ok_button" msgid="603075490581280343">"Taikyti"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Išjungti pranešimus"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Tylūs"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Numatytasis"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatinis"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Naudokite išskaidyto ekrano režimą su programa dešinėje"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Naudokite išskaidyto ekrano režimą su programa kairėje"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Naudoti viso ekrano režimą"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Įjungti darbalaukio pateikimo lange režimą"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Perjunkite į programą dešinėje arba apačioje išskaidyto ekrano režimu"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Perjunkite į programą kairėje arba viršuje išskaidyto ekrano režimu"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Slėpti šį programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ medijos valdiklį?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Dabartinio medijos seanso negalima paslėpti."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Slėpti"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ leidžiama iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> iš <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml index 46c6f6904875..3e1f3c702e61 100644 --- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Išjungta"</item> <item msgid="4875147066469902392">"Įjungta"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nepasiekiama"</item> <item msgid="5044688398303285224">"Išjungta"</item> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 06bc60102c48..0c030b7029f9 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Apkārtnes skaņas"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Pa kreisi"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Pa labi"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Apkārtnes skaņas"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Apkārtnes skaņas pa kreisi"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Apkārtnes skaņas pa labi"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Izvērst, lai rādītu atsevišķu kreiso un labo vadīklu"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sakļaut, lai rādītu vienotu vadīklu"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Izslēgt apkārtnes skaņas"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ieslēgt apkārtnes skaņas"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Rīki"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitri reāllaikā"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Iestatījumi"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Piezīme"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ieslēgta — ar sejas noteikšanu"</string> <string name="inline_done_button" msgid="6043094985588909584">"Gatavs"</string> <string name="inline_ok_button" msgid="603075490581280343">"Lietot"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Izslēgt paziņojumus"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Klusums"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Noklusējums"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automātiski"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Izmantot ekrāna sadalīšanu ar lietotni labajā pusē"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Izmantot ekrāna sadalīšanu ar lietotni kreisajā pusē"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Izmantot pilnekrāna režīmu"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Izmantot darbvirsmas logu režīmu"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pāriet uz lietotni pa labi/lejā, kamēr izmantojat sadalīto ekrānu."</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pāriet uz lietotni pa kreisi/augšā, kamēr izmantojat sadalīto ekrānu."</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena ekrāna uz otru"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pievienot elementu pozīcijā numur <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nederīga pozīcija."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozīcija numur <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Elements jau ir pievienots"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Elements ir pievienots"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Elements ir noņemts"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ātro iestatījumu redaktors."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Vai paslēpt šo lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> multivides vadīklu?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Pašreizējo multivides sesiju nevar paslēpt."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Paslēpt"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tiek atskaņots fails “<xliff:g id="SONG_NAME">%1$s</xliff:g>” (izpildītājs: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) no lietotnes <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> no <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml index 8e9268a97f6e..e55babc7317b 100644 --- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Izslēgts"</item> <item msgid="4875147066469902392">"Ieslēgts"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nav pieejams"</item> <item msgid="5044688398303285224">"Izslēgts"</item> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index c1a5d365c4b0..b798f457ee8b 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Опкружување"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Десно"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Опкружување"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Опкружување одлево"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Опкружување оддесно"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Прошири на одвоените контроли одлево и оддесно"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Собери на унифицирана контрола"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Исклучи го звукот на опкружувањето"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Вклучи го звукот на опкружувањето"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатки"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматски титлови"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Поставки"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се одблокира пристапот до микрофонот на уредот?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се одблокира пристапот до камерата на уредот?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Вклучено - според лице"</string> <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string> <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Исклучи известувања"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Безгласно"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Стандардно"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматски"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Користете поделен екран со апликацијата оддесно"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Користете поделен екран со апликацијата одлево"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Користете цел екран"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Користете „Режим со прозорци на работната површина“"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Префрлете се на апликацијата десно или долу при користењето поделен екран"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Префрлете се на апликацијата лево или горе при користењето поделен екран"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"При поделен екран: префрлете ги аплик. од едната на другата страна"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додавање на позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позицијата е погрешна."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плочката е веќе додадена"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Додадена е плочка"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Отстранета е плочка"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уредник за брзи поставки."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Да се скријат контролите за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Аудиовизуелнава сесија не може да се скрие."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриј"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> е пуштено на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml index 752c386113ed..8986ca5a7c86 100644 --- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Исклучено"</item> <item msgid="4875147066469902392">"Вклучено"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Недостапно"</item> <item msgid="5044688398303285224">"Исклучено"</item> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index fc004c06360c..eb7da33b02d2 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"സറൗണ്ടിംഗ്സ്"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ഇടത്"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"വലത്"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"സറൗണ്ടിംഗ്സ്"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ഇടത് സറൗണ്ടിംഗ്സ്"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"വലത് സറൗണ്ടിംഗ്സ്"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"വേർതിരിച്ച ഇടത്, വലത് നിയന്ത്രണങ്ങളിലേക്ക് വികസിപ്പിക്കുക"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ഏകീകൃത നിയന്ത്രണത്തിലേക്ക് ചുരുക്കുക"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"സറൗണ്ടിംഗ്സ് മ്യൂട്ട് ചെയ്യുക"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"സറൗണ്ടിംഗ്സ് അൺമ്യൂട്ട് ചെയ്യുക"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ടൂളുകൾ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"തത്സമയ ക്യാപ്ഷൻ"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ക്രമീകരണം"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"കുറിപ്പ്"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ഉപകരണ മൈക്രോഫോൺ അൺബ്ലോക്ക് ചെയ്യണോ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ഉപകരണ ക്യാമറ അൺബ്ലോക്ക് ചെയ്യണോ?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ഓണാണ് - ഫേസ് ബേസ്ഡ്"</string> <string name="inline_done_button" msgid="6043094985588909584">"പൂർത്തിയായി"</string> <string name="inline_ok_button" msgid="603075490581280343">"ബാധകമാക്കുക"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"അറിയിപ്പുകൾ ഓഫാക്കുക"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"നിശബ്ദം"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ഡിഫോൾട്ട്"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"സ്വയമേവ"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"വലതുവശത്തുള്ള ആപ്പിനൊപ്പം സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുക"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ഇടതുവശത്തുള്ള ആപ്പിനൊപ്പം സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുക"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"പൂർണ സ്ക്രീൻ ഉപയോഗിക്കുക"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ് ഉപയോഗിക്കുക"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറുക"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ ഇടതുവശത്തെ/മുകളിലെ ആപ്പിലേക്ക് മാറൂ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"സ്ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പിനുള്ള ഈ മീഡിയാ കൺട്രോൾ മറയ്ക്കണോ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"നിലവിലെ മീഡിയ സെഷൻ മറയ്ക്കാനാകില്ല."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"മറയ്ക്കുക"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുന്നു"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ൽ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml index e197c928e98a..a7098c9ef814 100644 --- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ഓഫാണ്"</item> <item msgid="4875147066469902392">"ഓണാണ്"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ലഭ്യമല്ല"</item> <item msgid="5044688398303285224">"ഓഫാണ്"</item> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 7d53c479a4b9..3adddc2d27ad 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Орчин тойрон"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Зүүн"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Баруун"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Орчин тойрон"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Зүүн талын орчин тойрны дуу"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Баруун талын орчин тойрны дуу"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Зүүн, баруун талын тусдаа тохиргоо руу дэлгэх"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Нэгдсэн тохиргоо руу хураах"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Орчин тойрны дууг хаах"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Орчин тойрны дууг нээх"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Хэрэгсэл"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Шууд тайлбар"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Тохиргоо"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Тэмдэглэл"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Төхөөрөмжийн микрофоныг блокоос гаргах уу?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Төхөөрөмжийн камерыг блокоос гаргах уу?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Асаалттай - Царайнд суурилсан"</string> <string name="inline_done_button" msgid="6043094985588909584">"Болсон"</string> <string name="inline_ok_button" msgid="603075490581280343">"Ашиглах"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Мэдэгдлийг унтраах"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Чимээгүй"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Өгөгдмөл"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автомат"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Аппыг баруун талд байгаагаар дэлгэцийг хуваахыг ашиглах"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Аппыг зүүн талд байгаагаар дэлгэцийг хуваахыг ашиглах"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Бүтэн дэлгэцийг ашиглах"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Дэлгэцийн цонх үүсгэх онцлогийг ашиглах"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Дэлгэц хуваахыг ашиглаж байхдаа баруун талд эсвэл доор байх апп руу сэлгэ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Дэлгэц хуваахыг ашиглаж байхдаа зүүн талд эсвэл дээр байх апп руу сэлгэ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Дэлгэц хуваах үеэр: аппыг нэгээс нөгөөгөөр солих"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> байрлалд нэмнэ үү"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Байрлал буруу байна."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> байрлал"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Хавтан аль хэдийн нэмсэн"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Хавтан нэмсэн"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Хавтанг хассан"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Шуурхай тохиргоо засварлагч."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Энэ медиа хяналтыг <xliff:g id="APP_NAME">%1$s</xliff:g>-д нуух уу?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Одоогийн медиа харилцан үйлдлийг нуух боломжгүй."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Нуух"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулж буй <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-н <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml index 7ca88e97777b..9b5a6e3c3037 100644 --- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Унтраалттай"</item> <item msgid="4875147066469902392">"Асаалттай"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Боломжгүй"</item> <item msgid="5044688398303285224">"Унтраалттай"</item> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 9eca378c63b3..08ef7b2e9cfc 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"जवळपासचे"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"डावे"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"उजवे"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"सभोवताली"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"डाव्या बाजूचा आवाज"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"उजव्या बाजूचा आवाज"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"डाव्या आणि उजव्या स्वतंत्र नियंत्रणांचा विस्तार करा"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"युनिफाइड नियंत्रणासाठी कोलॅप्स करा"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"जवळपासचे आवाज म्यूट करा"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"जवळपासचे आवाज अनम्यूट करा"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव्ह कॅप्शन"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"सेटिंग्ज"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"टीप"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिव्हाइसचा मायक्रोफोन अनब्लॉक करायचा आहे का?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिव्हाइसचा कॅमेरा अनब्लॉक करायचा आहे का?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"सुरू - चेहऱ्यावर आधारित"</string> <string name="inline_done_button" msgid="6043094985588909584">"पूर्ण झाले"</string> <string name="inline_ok_button" msgid="603075490581280343">"लागू करा"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचना बंद करा"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"सायलंट"</string> <string name="notification_alert_title" msgid="3656229781017543655">"डीफॉल्ट"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ऑटोमॅटिक"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ॲप उजवीकडे ठेवून स्प्लिट स्क्रीन वापरा"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ॲप डावीकडे ठेवून स्प्लिट स्क्रीन वापरा"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"फुल स्क्रीन वापरा"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"डेस्कटॉप विंडोइंग वापरा"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन वापरताना उजवीकडील किंवा खालील अॅपवर स्विच करा"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन वापरताना डावीकडील किंवा वरील अॅपवर स्विच करा"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीनदरम्यान: एक अॅप दुसऱ्या अॅपने बदला"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> स्थानावर जोडा"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"स्थान चुकीचे आहे."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थान <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"टाइल आधीपासून जोडली आहे"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोडली"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल काढून टाकली"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिंग्ज संपादक."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी हा मीडिया नियंत्रक लपवायचा आहे का?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"सध्याचे मीडिया सेशन लपवू शकत नाही."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लपवा"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले होत आहे"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> पैकी <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml index 58c4d06e39dd..a5930d9ff295 100644 --- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"बंद आहे"</item> <item msgid="4875147066469902392">"सुरू आहे"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"उपलब्ध नाही"</item> <item msgid="5044688398303285224">"बंद आहे"</item> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 7f7c77743b5d..5aec75608f76 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Nyahredam persekitaran"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatan"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sari Kata Langsung"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Tetapan"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Nyahsekat mikrofon peranti?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Nyahsekat kamera peranti?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Hidup - Berasaskan wajah"</string> <string name="inline_done_button" msgid="6043094985588909584">"Selesai"</string> <string name="inline_ok_button" msgid="603075490581280343">"Guna"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Matikan pemberitahuan"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Lalai"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatik"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gunakan skrin pisah dengan apl pada sebelah kanan"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gunakan skrin pisah dengan apl pada sebelah kiri"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gunakan skrin penuh"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gunakan tetingkap desktop"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Tukar kepada apl di sebelah kanan/bawah semasa menggunakan skrin pisah"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Tukar kepada apl di sebelah kiri/atas semasa menggunakan skrin pisah"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Semasa skrin pisah: gantikan apl daripada satu apl kepada apl lain"</string> @@ -1003,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan pada kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kedudukan tidak sah."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Jubin sudah ditambahkan"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Jubin ditambah"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Jubin dialih keluar"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor tetapan pantas."</string> @@ -1205,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kawalan media ini untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media semasa tidak dapat disembunyikan."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dimainkan daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> daripada <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml index 5a55b76feb5a..eca55a34e028 100644 --- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Mati"</item> <item msgid="4875147066469902392">"Hidup"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Tidak tersedia"</item> <item msgid="5044688398303285224">"Mati"</item> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 42cfe5eeb5fb..98f937b377e1 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ဝန်းကျင်အသံ"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ဘယ်"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ညာ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"ဝန်းကျင်အသံ"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ဘယ်ဘက် ဝန်းကျင်အသံ"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"ညာဘက် ဝန်းကျင်အသံ"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ဘယ်ညာခွဲထားသော ထိန်းချုပ်မှုများအဖြစ် ပိုပြပါ"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ပေါင်းစည်းထားသော ထိန်းချုပ်မှုအဖြစ် လျှော့ပြပါ"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ဝန်းကျင်အသံ ပိတ်ရန်"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ဝန်းကျင်အသံ ပြန်ဖွင့်ရန်"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"တူးလ်များ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"တိုက်ရိုက်စာတန်း"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ဆက်တင်များ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"မှတ်စု"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"စက်၏မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"စက်၏ကင်မရာကို ပြန်ဖွင့်မလား။"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ဖွင့် - မျက်နှာအခြေခံ"</string> <string name="inline_done_button" msgid="6043094985588909584">"ပြီးပြီ"</string> <string name="inline_ok_button" msgid="603075490581280343">"အသုံးပြုရန်"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"အကြောင်းကြားချက်များ ပိတ်ရန်"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"အသံပိတ်ရန်"</string> <string name="notification_alert_title" msgid="3656229781017543655">"မူလ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"အလိုအလျောက်"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"အက်ပ်ကို ညာ၌ထားကာ မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံးရန်"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"အက်ပ်ကို ဘယ်၌ထားကာ မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံးရန်"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ဖန်သားပြင်အပြည့် သုံးရန်"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ဒက်စ်တော့ဝင်းဒိုးမုဒ် သုံးရန်"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"မျက်နှာပြင်ခွဲ၍ပြသခြင်း သုံးစဉ် ညာ (သို့) အောက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသုံးစဉ် ဘယ် (သို့) အထက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထားသို့ ပေါင်းထည့်ရန်"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"နေရာ မမှန်ပါ။"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထား"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"အကွက်ငယ် ထည့်ပြီးဖြစ်သည်"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"အကွက်ငယ်ကို ထည့်ပြီးပါပြီ"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"အကွက်ငယ်ကို ဖယ်ရှားပြီးပါပြီ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် ဤမီဒီယာထိန်းချုပ်မှု ဖျောက်ထားမလား။"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"လက်ရှိ မီဒီယာစက်ရှင်ကို ဝှက်၍မရပါ။"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ၏ <xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%3$s</xliff:g> တွင် ဖွင့်ထားသည်"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> အနက် <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml index 778920506f03..2bd239043dea 100644 --- a/packages/SystemUI/res/values-my/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ပိတ်"</item> <item msgid="4875147066469902392">"ဖွင့်"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"မရနိုင်ပါ"</item> <item msgid="5044688398303285224">"ပိတ်"</item> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 3b6e891708bc..627ab44fba26 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Høyre"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgivelser"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Omgivelser til venstre"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Omgivelser til høyre"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Utvid til separate kontroller for venstre og høyre"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Skjul til samlet kontroll"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Kutt lyden for omgivelsene"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Slå på lyden for omgivelsene"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktøy"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Direkteteksting"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Innstillinger"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Merknad"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du oppheve blokkeringen av enhetsmikrofonen?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du oppheve blokkeringen av enhetskameraet?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"På – ansiktsbasert"</string> <string name="inline_done_button" msgid="6043094985588909584">"Ferdig"</string> <string name="inline_ok_button" msgid="603075490581280343">"Bruk"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Slå av varsler"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Lydløs"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Bruk delt skjerm med appen til høyre"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Bruk delt skjerm med appen til venstre"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Bruk fullskjerm"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Bruk datamaskinvinduer"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bytt til appen til høyre eller under mens du bruker delt skjerm"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bytt til appen til venstre eller over mens du bruker delt skjerm"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"I delt skjerm: Bytt ut en app"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Legg til posisjonen <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisjonen er ugyldig."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisjon <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Brikken er lagt til allerede"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"En infobrikke er lagt til"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"En infobrikke er fjernet"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsvindu for hurtiginnstillinger."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Vil du skjule denne mediekontrollen for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Den nåværende medieøkten kan ikke skjules."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spilles av fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml index 25b22052ea8d..fca868e98240 100644 --- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Av"</item> <item msgid="4875147066469902392">"På"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Utilgjengelig"</item> <item msgid="5044688398303285224">"Av"</item> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 936a0a653220..6090ca509036 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"वरपरका आवाज"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बायाँ"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"दायाँ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"सराउन्डिङ साउन्ड"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"बायाँतिरको सराउन्डिङ साउन्ड"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"दायाँतिरको सराउन्डिङ साउन्ड"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"दायाँ र बायाँतर्फको भोल्युम छुट्टाछुट्टै व्यवस्थापन गर्न भोल्युम प्यानल छुट्ट्याउनुहोस्"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"कोल्याप्स गरी एउटै कन्ट्रोल बनाउनुहोस्"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"वरपरका आवाज म्युट गर्नुहोस्"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"वरपरका आवाज अनम्युट गर्नुहोस्"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टुलहरू"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइभ क्याप्सन"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"सेटिङ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिभाइसको माइक्रोफोन अनब्लक गर्ने हो?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिभाइसको क्यामेरा अनब्लक गर्ने हो?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"अन छ - अनुहारमा आधारित"</string> <string name="inline_done_button" msgid="6043094985588909584">"सम्पन्न भयो"</string> <string name="inline_ok_button" msgid="603075490581280343">"लागू गर्नुहोस्"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचनाहरू अफ गर्नुहोस्"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"साइलेन्ट"</string> <string name="notification_alert_title" msgid="3656229781017543655">"डिफल्ट"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"स्वचालित"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"हालको एप दायाँ भागमा पारेर स्प्लिट स्क्रिन प्रयोग गर्नुहोस्"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"हालको एप बायाँ भागमा पारेर स्प्लिट स्क्रिन प्रयोग गर्नुहोस्"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"फुल स्क्रिन प्रयोग गर्नुहोस्"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"डेस्कटप विन्डोइङ प्रयोग गर्नुहोस्"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा दायाँ वा तलको एप चलाउनुहोस्"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा बायाँ वा माथिको एप चलाउनुहोस्"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रिन प्रयोग गरिएका बेला: एउटा स्क्रिनमा भएको एप अर्कोमा लैजानुहोस्"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल यो अवस्था <xliff:g id="POSITION">%1$d</xliff:g> मा हाल्नुहोस्"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"पोजिसन अवैध छ।"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"टाइल हालिसकिएको छ"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल हालियो"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाइयो"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिङ सम्पादक।"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> का हकमा यो मिडिया कन्ट्रोल लुकाउने हो?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"हालको मिडिया सत्र लुकाउन मिल्दैन।"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लुकाउनुहोस्"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बज्दै छ"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> मध्ये <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml index fe812f846e41..71f415a3d0ef 100644 --- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"अफ छ"</item> <item msgid="4875147066469902392">"अन छ"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"उपलब्ध छैन"</item> <item msgid="5044688398303285224">"अफ छ"</item> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 2a81bb424c8e..ebe9ad475229 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Omgevingsgeluid aanzetten"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live ondertiteling"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Instellingen"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notitie"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Microfoon van apparaat niet meer blokkeren?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Apparaatcamera niet meer blokkeren?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aan: op basis van gezicht"</string> <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string> <string name="inline_ok_button" msgid="603075490581280343">"Toepassen"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Meldingen uitzetten"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Standaard"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gesplitst scherm gebruiken met de app aan de rechterkant"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gesplitst scherm gebruiken met de app aan de linkerkant"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Volledig scherm gebruiken"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Desktopvensterfuncties gebruiken"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Naar de app rechts of onderaan gaan als je een gesplitst scherm gebruikt"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Naar de app links of bovenaan gaan als je een gesplitst scherm gebruikt"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijdens gesplitst scherm: een app vervangen door een andere"</string> @@ -1003,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Toevoegen aan positie <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positie ongeldig."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Positie <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tegel is al toegevoegd"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tegel toegevoegd"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tegel verwijderd"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor voor \'Snelle instellingen\'."</string> @@ -1205,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Deze mediabediening verbergen voor <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"De huidige mediasessie kan niet worden verborgen."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Verbergen"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wordt afgespeeld via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml index bb8fbe0604dc..01de4cbc574f 100644 --- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Uit"</item> <item msgid="4875147066469902392">"Aan"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Niet beschikbaar"</item> <item msgid="5044688398303285224">"Uit"</item> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index e12fe7ecb39e..8569c7aaad2e 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ପରିପାର୍ଶ୍ୱ"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ବାମ"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ଡାହାଣ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"ପରିପାର୍ଶ୍ୱ"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ବାମ ପରିପାର୍ଶ୍ୱ"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"ଡାହାଣ ପରିପାର୍ଶ୍ୱ"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ବାମ ଏବଂ ଡାହାଣ ଅଲଗା ନିୟନ୍ତ୍ରଣକୁ ବିସ୍ତାର କରନ୍ତୁ"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ଏକତ୍ରିତ ନିୟନ୍ତ୍ରଣକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ପରିପାର୍ଶ୍ୱକୁ ମ୍ୟୁଟ କରନ୍ତୁ"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ପରିପାର୍ଶ୍ୱକୁ ଅନମ୍ୟୁଟ କରନ୍ତୁ"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ଟୁଲ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ଲାଇଭ କେପ୍ସନ"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ସେଟିଂସ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"ନୋଟ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ କରିବେ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ଡିଭାଇସର କେମେରାକୁ ଅନବ୍ଲକ କରିବେ?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ଚାଲୁ ଅଛି - ଫେସ-ଆଧାରିତ"</string> <string name="inline_done_button" msgid="6043094985588909584">"ହୋଇଗଲା"</string> <string name="inline_ok_button" msgid="603075490581280343">"ଲାଗୁ କରନ୍ତୁ"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ବିଜ୍ଞପ୍ତି ବନ୍ଦ କରନ୍ତୁ"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ନୀରବ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ଡିଫଲ୍ଟ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ସ୍ୱଚାଳିତ"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ଡାହାଣରେ ଆପ ସହିତ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ବାମରେ ଆପ ସହିତ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ବ୍ୟବହାର କରନ୍ତୁ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ଡେସ୍କଟପ ୱିଣ୍ଡୋଇଂ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ଅବସ୍ଥିତିରେ ଯୋଗ କରନ୍ତୁ"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ଅବସ୍ଥିତି ଅବୈଧ ଅଟେ।"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ଅବସ୍ଥିତି <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ପୂର୍ବରୁ ଟାଇଲକୁ ଯୋଗ କରାଯାଇଛି"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ଟାଇଲ୍ ଯୋଗ କରାଯାଇଛି"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ଟାଇଲ୍ କାଢ଼ି ଦିଆଯାଇଛି"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଏଡିଟର୍।"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଏହି ମିଡିଆ ନିୟନ୍ତ୍ରଣକୁ ଲୁଚାଇବେ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ବର୍ତ୍ତମାନର ମିଡିଆ ସେସନକୁ ଲୁଚାଯାଇପାରିବ ନାହିଁ।"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ଲୁଚାନ୍ତୁ"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ରୁ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml index eae984b6c1f3..37d3c95629f5 100644 --- a/packages/SystemUI/res/values-or/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ବନ୍ଦ ଅଛି"</item> <item msgid="4875147066469902392">"ଚାଲୁ ଅଛି"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ଉପଲବ୍ଧ ନାହିଁ"</item> <item msgid="5044688398303285224">"ବନ୍ଦ ଅଛି"</item> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 26d26dc1e795..c7735a21b25b 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ਆਲੇ-ਦੁਆਲੇ"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ਖੱਬੇ"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ਸੱਜੇ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"ਸਰਾਊਂਡ ਸਾਊਂਡ"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ਖੱਬੇ ਪਾਸੇ ਦਾ ਸਰਾਊਂਡ ਸਾਊਂਡ"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"ਸੱਜੇ ਪਾਸੇ ਦਾ ਸਰਾਊਂਡ ਸਾਊਂਡ"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ਖੱਬੇ ਅਤੇ ਸੱਜੇ ਪਾਸੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਵੱਖ-ਵੱਖ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਵਿਸਤਾਰ ਕਰੋ"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ਏਕੀਕ੍ਰਿਤ ਕੰਟਰੋਲ \'ਤੇ ਜਾਣ ਲਈ ਸਮੇਟੋ"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ਆਲੇ-ਦੁਆਲੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਮਿਊਟ ਕਰੋ"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ਆਲੇ-ਦੁਆਲੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਅਣਮਿਊਟ ਕਰੋ"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ਟੂਲ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ਲਾਈਵ ਸੁਰਖੀਆਂ"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ਸੈਟਿੰਗਾਂ"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"ਨੋਟ-ਕਥਨ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ਚਾਲੂ ਹੈ - ਚਿਹਰਾ-ਆਧਾਰਿਤ"</string> <string name="inline_done_button" msgid="6043094985588909584">"ਹੋ ਗਿਆ"</string> <string name="inline_ok_button" msgid="603075490581280343">"ਲਾਗੂ ਕਰੋ"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ਸ਼ਾਂਤ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ਸਵੈਚਲਿਤ"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ਸੱਜੇ ਪਾਸੇ ਵਾਲੀ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ਖੱਬੇ ਪਾਸੇ ਵਾਲੀ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ਡੈਸਕਟਾਪ \'ਤੇ ਇੱਕ ਤੋਂ ਵੱਧ ਵਿੰਡੋਆਂ ਦਿਖਾਉਣ ਵਾਲੀ ਸੁਵਿਧਾ ਵਰਤੋ"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਸੱਜੇ ਜਾਂ ਹੇਠਾਂ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਖੱਬੇ ਜਾਂ ਉੱਪਰ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਨੂੰ ਬਦਲੋ"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ਸਥਾਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ਮੌਜੂਦਾ ਥਾਂ ਅਵੈਧ ਹੈ।"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ਸਥਾਨ <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ਟਾਇਲ ਨੂੰ ਪਹਿਲਾਂ ਹੀ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ਟਾਇਲ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ਟਾਇਲ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਇਹ ਮੀਡੀਆ ਕੰਟਰੋਲ ਲੁਕਾਉਣਾ ਹੈ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ਮੌਜੂਦਾ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ਵਿੱਚੋਂ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml index 2baff30ad6d6..43b8734bb274 100644 --- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ਬੰਦ ਹੈ"</item> <item msgid="4875147066469902392">"ਚਾਲੂ ਹੈ"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ਅਣਉਪਲਬਧ ਹੈ"</item> <item msgid="5044688398303285224">"ਬੰਦ ਹੈ"</item> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 6b526f292507..7c490736651c 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Otoczenie"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Po lewej"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Po prawej"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Otoczenie"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Otoczenie z lewej strony"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Otoczenie z prawej strony"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozwiń, aby oddzielić elementy sterujące po lewej i po prawej stronie"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zwiń do ujednoliconego sterowania"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Wycisz otoczenie"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Wyłącz wyciszenie otoczenia"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Narzędzia"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Napisy na żywo"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ustawienia"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notatka"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Włączono – na podstawie twarzy"</string> <string name="inline_done_button" msgid="6043094985588909584">"Gotowe"</string> <string name="inline_ok_button" msgid="603075490581280343">"Zastosuj"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Wyłącz powiadomienia"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Ciche"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Domyślne"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatycznie"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Podziel ekran z aplikacją widoczną po prawej"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Podziel ekran z aplikacją widoczną po lewej"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Użyj trybu pełnoekranowego"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Używaj trybu okien na pulpicie"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Przełącz się na aplikację po prawej lub poniżej na podzielonym ekranie"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Przełącz się na aplikację po lewej lub powyżej na podzielonym ekranie"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Podczas podzielonego ekranu: zastępowanie aplikacji"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodaj w pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nieprawidłowa pozycja."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozycja <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kafelek został już dodany"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dodano kartę"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Usunięto kartę"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Edytor szybkich ustawień."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ukryć sterowanie multimediami w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Nie można ukryć tej sesji multimediów."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Aplikacja <xliff:g id="APP_LABEL">%3$s</xliff:g> odtwarza utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml index bd3a828c868f..abc1867f0660 100644 --- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Wyłączone"</item> <item msgid="4875147066469902392">"Włączone"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Niedostępny"</item> <item msgid="5044688398303285224">"Wyłączona"</item> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 07f87ee1a0cc..40b85cc0da14 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Lado direito"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Som ambiente"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambiente à esquerda"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambiente à direita"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Abrir para controles separados da esquerda e da direita"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Fechar para controle unificado"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar som ambiente"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ativar som ambiente"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configurações"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada (reconhecimento facial)"</string> <string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosas"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar a tela dividida com o app à direita"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar a tela dividida com o app à esquerda"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar tela cheia"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar modo de janela para computador"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"O bloco já foi adicionado"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controle de mídia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Não é possível ocultar a sessão de mídia atual."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml index 0233a36b176e..30e45feb3c13 100644 --- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desativado"</item> <item msgid="4875147066469902392">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Indisponível"</item> <item msgid="5044688398303285224">"Apagada"</item> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index de1057d543c8..934c7176d4a3 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada – Com base no rosto"</string> <string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Predefinição"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use o ecrã dividido com a app à direita"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use o ecrã dividido com a app à esquerda"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use o ecrã inteiro"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use janelas de computador"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para a app à direita ou abaixo enquanto usa o ecrã dividido"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mude para a app à esquerda ou acima enquanto usa o ecrã dividido"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante o ecrã dividido: substituir uma app por outra"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar controlo de multimédia para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Não pode ocultar a sessão de multimédia atual."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> em reprodução a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml index 3beca27a1d29..42a465ea415f 100644 --- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desligado"</item> <item msgid="4875147066469902392">"Ligado"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Indisponível"</item> <item msgid="5044688398303285224">"Desligada"</item> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 07f87ee1a0cc..40b85cc0da14 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Lado direito"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Som ambiente"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambiente à esquerda"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambiente à direita"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Abrir para controles separados da esquerda e da direita"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Fechar para controle unificado"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar som ambiente"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ativar som ambiente"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configurações"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada (reconhecimento facial)"</string> <string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosas"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar a tela dividida com o app à direita"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar a tela dividida com o app à esquerda"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar tela cheia"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar modo de janela para computador"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"O bloco já foi adicionado"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controle de mídia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Não é possível ocultar a sessão de mídia atual."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml index 0233a36b176e..30e45feb3c13 100644 --- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Desativado"</item> <item msgid="4875147066469902392">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Indisponível"</item> <item msgid="5044688398303285224">"Apagada"</item> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index a6b4983aa0ae..3f8324e3b7f3 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Împrejurimi"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Stânga"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dreapta"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Împrejurimi"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Împrejurimi din stânga"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Împrejurimi din dreapta"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Extinde comenzile separate la stânga și la dreapta"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Restrânge la comanda unificată"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Dezactivează sunetul ambiental"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Activează sunetul ambiental"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Instrumente"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrări live"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Setări"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notă"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblochezi microfonul dispozitivului?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblochezi camera dispozitivului?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activată – În funcție de chip"</string> <string name="inline_done_button" msgid="6043094985588909584">"Gata"</string> <string name="inline_ok_button" msgid="603075490581280343">"Aplică"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Dezactivează notificările"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Silențios"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Prestabilite"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automat"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Folosește ecranul împărțit cu aplicația în dreapta"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Folosește ecranul împărțit cu aplicația în stânga"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Folosește ecranul complet"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Folosește funcția de windowing pe desktop"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Treci la aplicația din dreapta sau de mai jos cu ecranul împărțit"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Treci la aplicația din stânga sau de mai sus cu ecranul împărțit"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adaugă pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Poziție nevalidă."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Cardul a fost adăugat deja"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Cardul a fost adăugat"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Cardul a fost eliminat"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editorul pentru setări rapide."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ascunzi comanda media pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Sesiunea media actuală nu se poate ascunde."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ascunde"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se redă în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> din <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml index b55598725a0f..56460771381d 100644 --- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Dezactivată"</item> <item msgid="4875147066469902392">"Activată"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Indisponibilă"</item> <item msgid="5044688398303285224">"Dezactivată"</item> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 693024bcb274..450d048da5bf 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Не заглушать окружающие звуки"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменты"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматические субтитры"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Настройки"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Заметка"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Включить (на основе распознавания лиц)"</string> <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string> <string name="inline_ok_button" msgid="603075490581280343">"Применить"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Выключить уведомления"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Без звука"</string> <string name="notification_alert_title" msgid="3656229781017543655">"По умолчанию"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматически"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Разделить экран и поместить открытое приложение справа"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Разделить экран и поместить открытое приложение слева"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Полноэкранный режим"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Использовать компьютерные окна"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти к приложению справа или внизу на разделенном экране"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Перейти к приложению слева или вверху на разделенном экране"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"В режиме разделения экрана заменить одно приложение другим"</string> @@ -1003,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Недопустимое расположение."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Параметр уже добавлен"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Панель добавлена"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Панель удалена"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор быстрых настроек."</string> @@ -1205,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Скрыть этот элемент в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Этот мультимедийный сеанс невозможно скрыть."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скрыть"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Воспроизводится медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\"."</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> из <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml index 8279183345a8..9ffa7f1f4152 100644 --- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Откл."</item> <item msgid="4875147066469902392">"Вкл."</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Функция недоступна"</item> <item msgid="5044688398303285224">"Откл."</item> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 8632e13397d2..c6326f27c478 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"වටපිටාව"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"වම"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"දකුණ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"වටපිටාව"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"වම් වටපිටාව"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"දකුණු වටපිටාව"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"වමට සහ දකුණට වෙන් වූ පාලන වෙත පුළුල් කරන්න"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ඒකාබද්ධ පාලනයට හකුළන්න"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"අවට පරිසරය නිහඬ කරන්න"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"අවට නිහඬ නොකරන්න"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"මෙවලම්"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"සජීවී සිරස්තල"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"සැකසීම්"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"සටහන"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"උපාංග මයික්රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"උපාංග කැමරාව අවහිර කිරීම ඉවත් කරන්නද?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ක්රියාත්මකයි - මුහුණ-පදනම්ව"</string> <string name="inline_done_button" msgid="6043094985588909584">"නිමයි"</string> <string name="inline_ok_button" msgid="603075490581280343">"යොදන්න"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"දැනුම්දීම් අක්රිය කරන්න"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"නිහඬ"</string> <string name="notification_alert_title" msgid="3656229781017543655">"පෙරනිමි"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ස්වයංක්රිය"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"දකුණේ යෙදුම සමග බෙදීම් තිරය භාවිතා කරන්න"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"වම් පැත්තේ යෙදුම සමග බෙදීම් තිරය භාවිතා කරන්න"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"පූර්ණ තිරය භාවිතා කරන්න"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ඩෙස්ක්ටොප් කවුළුකරණය භාවිතා කරන්න"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"බෙදුම් තිරය භාවිත කරන අතරතුර දකුණේ හෝ පහළින් ඇති යෙදුමට මාරු වන්න"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"බෙදුම් තිරය භාවිත කරන අතරතුර වමේ හෝ ඉහළ ඇති යෙදුමට මාරු වන්න"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්රතිස්ථාපනය කරන්න"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ස්ථානයට එක් කරන්න"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ස්ථානය අවලංගුයි."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ටයිලය දැනටමත් එක් කර ඇත"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ටයිල් එක එක් කරන ලදි"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ටයිල් ඉවත් කරන ලදි"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ඉක්මන් සැකසුම් සංස්කාරකය."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා මෙම මාධ්ය පාලනය වසන්නද?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"වත්මන් මාධ්ය සැසිය සැඟවිය නොහැකිය."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"සඟවන්න"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>ගේ <xliff:g id="SONG_NAME">%1$s</xliff:g> ගීතය <xliff:g id="APP_LABEL">%3$s</xliff:g> වෙතින් ධාවනය වෙමින් පවතී"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>කින් <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml index 9397ca7221e9..7eeaefd4e546 100644 --- a/packages/SystemUI/res/values-si/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"අක්රියයි"</item> <item msgid="4875147066469902392">"සක්රියයි"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"නොමැත"</item> <item msgid="5044688398303285224">"අක්රියයි"</item> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 03509f314b2b..fe1dbbd926d1 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Zapnúť zvuk okolia"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Živý prepis"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Nastavenia"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Chcete odblokovať kameru zariadenia?"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Zapnuté – podľa tváre"</string> <string name="inline_done_button" msgid="6043094985588909584">"Hotovo"</string> <string name="inline_ok_button" msgid="603075490581280343">"Použiť"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Vypnúť upozornenia"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Tiché"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Predvolené"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Rozdelenie obrazovky, aktuálna aplikácia vpravo"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Rozdelenie obrazovky, aktuálna aplikácia vľavo"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Používať celú obrazovku"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Používať windowing na pracovnej ploche"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prechod na aplikáciu vpravo alebo dole pri rozdelenej obrazovke"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prechod na aplikáciu vľavo alebo hore pri rozdelenej obrazovke"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Chcete tento ovládač médií pre <xliff:g id="APP_NAME">%1$s</xliff:g> skryť?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuálna relácia média sa nedá skryť."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sa prehráva z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml index 3e618846a6c3..5a4ce99bf63e 100644 --- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Vypnuté"</item> <item msgid="4875147066469902392">"Zapnuté"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nie je k dispozícii"</item> <item msgid="5044688398303285224">"Vypnuté"</item> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 10a236c0ed5b..22d21bc47731 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Vklopljeno – na podlagi obraza"</string> <string name="inline_done_button" msgid="6043094985588909584">"Končano"</string> <string name="inline_ok_button" msgid="603075490581280343">"Uporabi"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Izklopi obvestila"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Tiho"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Privzeto"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Samodejno"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Uporaba razdeljenega zaslona z aplikacijo na desni"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Uporaba razdeljenega zaslona z aplikacijo na levi"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Uporaba celozaslonskega načina"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Uporaba namiznega načina prikaza več oken hkrati"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Preklop na aplikacijo desno ali spodaj med uporabo razdeljenega zaslona"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Preklop na aplikacijo levo ali zgoraj med uporabo razdeljenega zaslona"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Pri razdeljenem zaslonu: medsebojna zamenjava aplikacij"</string> @@ -1203,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite skriti ta nadzor predstavnosti za <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutne seje predstavnosti ni mogoče skriti."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se predvaja iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml index 814680254a8c..8f243dedef9c 100644 --- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Izklopljeno"</item> <item msgid="4875147066469902392">"Vklopljeno"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Ni na voljo"</item> <item msgid="5044688398303285224">"Izklopljeno"</item> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index a32fc8aaf267..203b9faa6730 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambienti rrethues"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Majtas"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Djathtas"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ambienti rrethues"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambienti rrethues majtas"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambienti rrethues djathtas"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Zgjero te kontrollet e veçuara majtas dhe djathtas"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Palos te kontrolli i unifikuar"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Vendos në heshtje ambientin rrethues"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Anulo vendosjen në heshtje të ambientit rrethues"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Veglat"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titrat në çast"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Cilësimet"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Shënim"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Të zhbllokohet mikrofoni i pajisjes?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Të zhbllokohet kamera e pajisjes?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktiv - Në bazë të fytyrës"</string> <string name="inline_done_button" msgid="6043094985588909584">"U krye"</string> <string name="inline_ok_button" msgid="603075490581280343">"Zbato"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Çaktivizo njoftimet"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Në heshtje"</string> <string name="notification_alert_title" msgid="3656229781017543655">"E parazgjedhur"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatike"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Përdor ekranin e ndarë me aplikacionin në të djathtë"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Përdor ekranin e ndarë me aplikacionin në të majtë"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Përdor ekranin e plotë"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Përdor ndërfaqen me dritare në desktop"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Kalo tek aplikacioni djathtas ose poshtë kur përdor ekranin e ndarë"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Kalo tek aplikacioni në të majtë ose sipër kur përdor ekranin e ndarë"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Gjatë ekranit të ndarë: zëvendëso një aplikacion me një tjetër"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Shto te pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicion i pavlefshëm."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Pllakëza është shtuar tashmë"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pllakëza u shtua"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pllakëza u hoq"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redaktori i cilësimeve të shpejta."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Të fshihet kontrolluesi i medias për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Seanca aktuale e medias nuk mund të fshihet."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fshih"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> po luhet nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> nga <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml index 7ee56318d749..ac1409990bcd 100644 --- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Joaktiv"</item> <item msgid="4875147066469902392">"Aktiv"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Nuk ofrohet"</item> <item msgid="5044688398303285224">"Joaktiv"</item> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index f99301c44e7d..97ca62a420c3 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружење"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Десно"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Окружење"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Лево окружење"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Десно окружење"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Прошири на контроле раздвојене на леву и десну страну"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Скупи у јединствену контролу"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Искључи звук окружења"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Укључи звук окружења"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатке"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Титл уживо"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Подешавања"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Укључено – на основу лица"</string> <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string> <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Искључи обавештења"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Нечујно"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Подразумевано"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Користи подељени екран са апликацијом с десне стране"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Користи подељени екран са апликацијом с леве стране"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Користи приказ преко целог екрана"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Користи прозорски приказ на рачунару"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пређи у апликацију здесна или испод док је подељен екран"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пређите у апликацију слева или изнад док користите подељени екран"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"У режиму подељеног екрана: замена једне апликације другом"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиција је неважећа."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плочица је већ додата"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плочица је додата"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плочица је уклоњена"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Желите да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml index df9e574fe053..e7e34aea2bee 100644 --- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Искључено"</item> <item msgid="4875147066469902392">"Укључено"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Недоступно"</item> <item msgid="5044688398303285224">"Искључено"</item> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 0085ed26e4cd..4cdc37d72176 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivningsläge"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vänster"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Höger"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgivningsljud"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Omgivningsljud till vänster"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Omgivningsljud till höger"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Utöka till kontroller till vänster och höger"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Komprimera till enhetlig kontroll"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Stäng av omgivningsljudet"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Slå på omgivningsljudet"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktyg"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Inställningar"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Anteckning"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vill du återaktivera enhetens mikrofon?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vill du återaktivera enhetens kamera?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"På – ansiktsbaserad"</string> <string name="inline_done_button" msgid="6043094985588909584">"Klart"</string> <string name="inline_ok_button" msgid="603075490581280343">"Tillämpa"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Inaktivera aviseringar"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Tyst"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automatiskt"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Använd delad skärm med appen till höger"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Använd delad skärm med appen till vänster"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Använd helskärm"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Använd fönsterplacering på datorn"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Byt till appen till höger eller nedanför när du använder delad skärm"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Byt till appen till vänster eller ovanför när du använder delad skärm"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Med delad skärm: ersätt en app med en annan"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Vill du dölja denna mediastyrning för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuella mediesessionen kan inte döljas."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spelas upp från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml index 76822d073668..7ec70eac7adc 100644 --- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Av"</item> <item msgid="4875147066469902392">"På"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Inte tillgängligt"</item> <item msgid="5044688398303285224">"Av"</item> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index b7d208a95d85..1cb61fdbab01 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Mazingira"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kushoto"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kulia"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Mandhari"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Mandhari ya kushoto"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Mandhari ya kulia"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Panua iwe vidhibiti vilivyotenganishwa kushoto na kulia"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kunja iwe kidhibiti cha pamoja"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Zima sauti ya mazingira"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Rejesha sauti ya mazingira"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Zana"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Manukuu Papo Hapo"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Mipangilio"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Dokezo"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Imewashwa - Inayolenga nyuso"</string> <string name="inline_done_button" msgid="6043094985588909584">"Nimemaliza"</string> <string name="inline_ok_button" msgid="603075490581280343">"Tumia"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Zima arifa"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Kimya"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Chaguomsingi"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatiki"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Tumia hali ya kugawa skrini na programu ya sasa iwe upande wa kulia"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Tumia hali ya kugawa skrini na programu ya sasa iwe upande wa kushoto"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Tumia skrini nzima"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Tumia hali ya madirisha ya kompyuta ya mezani"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Badilisha ili uende kwenye programu iliyo kulia au chini unapotumia hali ya kugawa skrini"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Badilisha uende kwenye programu iliyo kushoto au juu unapotumia hali ya kugawa skrini"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Ukigawanya skrini: badilisha kutoka programu moja hadi nyingine"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ongeza kwenye nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nafasi si sahihi."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tayari umeweka kigae"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kigae kimewekwa"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kigae kimeondolewa"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kihariri cha Mipangilio ya haraka."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Kipindi cha sasa cha maudhui hakiwezi kufichwa."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> unacheza katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> kati ya <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml index a16a7b7792c2..9e262819f560 100644 --- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Kimezimwa"</item> <item msgid="4875147066469902392">"Kimewashwa"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Hakipatikani"</item> <item msgid="5044688398303285224">"Imezimwa"</item> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 473be6f14093..3109a13290af 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"சுற்றுப்புறங்கள்"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"இடது"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"வலது"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"சுற்றுப்புறங்கள்"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"இடதுபுறச் சுற்றுப்புறங்கள்"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"வலதுபுறச் சுற்றுப்புறங்கள்"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"இடது மற்றும் வலதுபுறம் உள்ள கட்டுப்பாடுகளை விரிவாக்கும்"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ஒருங்கிணைந்த கட்டுப்பாட்டுக்குச் சுருக்கும்"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"சுற்றுப்புறங்களின் ஒலியை அடக்கும்"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"சுற்றுப்புறங்களின் ஒலியை இயக்கும்"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"கருவிகள்"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"உடனடி வசனம்"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"அமைப்புகள்"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"குறிப்பு"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"சாதனத்தின் மைக்ரோஃபோனுக்கான தடுப்பை நீக்கவா?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"சாதனத்தின் கேமராவுக்கான தடுப்பை நீக்கவா?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ஆன் - முகம் அடிப்படையிலானது"</string> <string name="inline_done_button" msgid="6043094985588909584">"முடிந்தது"</string> <string name="inline_ok_button" msgid="603075490581280343">"பயன்படுத்து"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"அறிவிப்புகளை முடக்கு"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"சைலன்ட்"</string> <string name="notification_alert_title" msgid="3656229781017543655">"இயல்புநிலை"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"தானியங்கு"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ஆப்ஸ் வலதுபுறம் வரும்படி திரைப் பிரிப்பைப் பயன்படுத்துதல்"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ஆப்ஸ் இடதுபுறம் வரும்படி திரைப் பிரிப்பைப் பயன்படுத்துதல்"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"முழுத்திரையைப் பயன்படுத்து"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"டெஸ்க்டாப் சாளரமாக்குதலைப் பயன்படுத்துதல்"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது வலது/கீழ் உள்ள ஆப்ஸுக்கு மாறுதல்"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது இடது/மேலே உள்ள ஆப்ஸுக்கு மாறுதல்"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"திரைப் பிரிப்பின்போது: ஓர் ஆப்ஸுக்குப் பதிலாக மற்றொன்றை மாற்றுதல்"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"நிலை தவறானது."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"இடம்: <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"கட்டம் ஏற்கெனவே சேர்க்கப்பட்டது"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"கட்டம் சேர்க்கப்பட்டது"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"கட்டம் அகற்றப்பட்டது"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான இந்த மீடியா கட்டுப்பாடுகளை மறைக்கவா?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"தற்போதைய மீடியா அமர்வை மறைக்க முடியாது."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"மறை"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடல் <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேயாகிறது"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml index dc1c514c559d..d3773a761c37 100644 --- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"முடக்கப்பட்டுள்ளது"</item> <item msgid="4875147066469902392">"இயக்கப்பட்டுள்ளது"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"கிடைக்கவில்லை"</item> <item msgid="5044688398303285224">"முடக்கப்பட்டுள்ளது"</item> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index a75dd225bb24..1bf3ab2e913f 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -794,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"\'ముఖం ఆధారం\'ను - ఆన్ చేయండి"</string> <string name="inline_done_button" msgid="6043094985588909584">"పూర్తయింది"</string> <string name="inline_ok_button" msgid="603075490581280343">"అప్లయి చేయి"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"నోటిఫికేషన్లను ఆఫ్ చేయి"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"నిశ్శబ్దం"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ఆటోమేటిక్ సెట్టింగ్"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"ఆటోమేటిక్"</string> @@ -905,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"కుడి వైపు ప్రస్తుత యాప్తో స్ప్లిట్ స్క్రీన్ను ఉపయోగించండి"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ఎడమ వైపు ప్రస్తుత యాప్తో స్ప్లిట్ స్క్రీన్ను ఉపయోగించండి"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ఫుల్ స్క్రీన్ను ఉపయోగించండి"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"డెస్క్టాప్ విండోయింగ్ను ఉపయోగించండి"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు కుడి లేదా కింద యాప్నకు మారండి"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు ఎడమ లేదా పైన యాప్నకు మారండి"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"స్ప్లిట్ స్క్రీన్ సమయంలో: ఒక దాన్నుండి మరో దానికి యాప్ రీప్లేస్ చేయండి"</string> @@ -993,8 +993,7 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"తక్కువ ప్రాధాన్యత నోటిఫికేషన్ చిహ్నాలను చూపించు"</string> <string name="other" msgid="429768510980739978">"ఇతరం"</string> - <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) --> - <skip /> + <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"టైల్ సైజ్ను టోగుల్ చేయండి"</string> <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"టైల్ను తీసివేయండి"</string> <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"చివరి పొజిషన్కు టైల్ను జోడించండి"</string> <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"టైల్ను తరలించండి"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం ఈ మీడియా కంట్రోల్ను దాచి ఉంచాలా?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ప్రస్తుత మీడియా సెషన్ను దాచడం సాధ్యం కాదు."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచండి"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్లు"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>లో <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string> @@ -1548,10 +1546,8 @@ <string name="overview_edu_toast_content" msgid="5797030644017804518">"ఇటీవలి యాప్లను చూడటానికి, టచ్ప్యాడ్లో మూడు వేళ్లతో పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string> <string name="all_apps_edu_toast_content" msgid="8807496014667211562">"మీ యాప్లన్నింటినీ చూడటానికి, మీ కీబోర్డ్లో యాక్షన్ కీని నొక్కండి"</string> <string name="redacted_notification_single_line_title" msgid="212019960919261670">"దాచిపెట్టినది"</string> - <!-- no translation found for public_notification_single_line_text (3576190291791654933) --> - <skip /> - <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) --> - <skip /> + <string name="public_notification_single_line_text" msgid="3576190291791654933">"చూడటానికి అన్లాక్ చేయండి"</string> + <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"కోడ్ను చూడటానికి అన్లాక్ చేయండి"</string> <string name="contextual_education_dialog_title" msgid="4630392552837487324">"సందర్భోచిత విద్య"</string> <string name="back_edu_notification_title" msgid="5624780717751357278">"వెనుకకు వెళ్లడానికి మీ టచ్ప్యాడ్ను ఉపయోగించండి"</string> <string name="back_edu_notification_content" msgid="2497557451540954068">"మూడు వేళ్లతో ఎడమ / కుడి వైపునకు స్వైప్ చేయండి. మరిన్ని సంజ్ఞల గురించి తెలుసుకోవడానికి ట్యాప్ చేయండి."</string> diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml index d118429e7c55..72343a33a082 100644 --- a/packages/SystemUI/res/values-te/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ఆఫ్లో ఉంది"</item> <item msgid="4875147066469902392">"ఆన్లో ఉంది"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"అందుబాటులో లేదు"</item> <item msgid="5044688398303285224">"ఆఫ్లో ఉంది"</item> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index e1413f2ebe65..99aca811b873 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -432,8 +432,7 @@ <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"เปิดเสียงแวดล้อม"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"เครื่องมือ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"คำบรรยายสด"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"การตั้งค่า"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"จดบันทึก"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"เลิกบล็อกไมโครโฟนของอุปกรณ์ใช่ไหม"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"เลิกบล็อกกล้องของอุปกรณ์ใช่ไหม"</string> @@ -795,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"เปิด - ตามใบหน้า"</string> <string name="inline_done_button" msgid="6043094985588909584">"เสร็จสิ้น"</string> <string name="inline_ok_button" msgid="603075490581280343">"ใช้"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ปิดการแจ้งเตือน"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"ปิดเสียง"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ค่าเริ่มต้น"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"อัตโนมัติ"</string> @@ -906,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"ใช้โหมดแยกหน้าจอโดยให้แอปอยู่ด้านขวา"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"ใช้โหมดแยกหน้าจอโดยให้แอปอยู่ด้านซ้าย"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ใช้โหมดเต็มหน้าจอ"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ใช้หน้าต่างเดสก์ท็อป"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"เปลี่ยนไปใช้แอปทางด้านขวาหรือด้านล่างขณะใช้โหมดแยกหน้าจอ"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"เปลี่ยนไปใช้แอปทางด้านซ้ายหรือด้านบนขณะใช้โหมดแยกหน้าจอ"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"ระหว่างใช้โหมดแยกหน้าจอ: เปลี่ยนแอปหนึ่งเป็นอีกแอปหนึ่ง"</string> @@ -1204,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"ซ่อนตัวควบคุมสื่อนี้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ซ่อนเซสชันสื่อในปัจจุบันไม่ได้"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ซ่อน"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"กำลังเปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> จาก <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml index 9fba3bdd9d6b..b9690568d136 100644 --- a/packages/SystemUI/res/values-th/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"ปิด"</item> <item msgid="4875147066469902392">"เปิด"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"ไม่พร้อมใช้งาน"</item> <item msgid="5044688398303285224">"ปิด"</item> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index aff1621dd4cf..726cf21e84e4 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -423,12 +423,9 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Paligid"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kaliwa"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Paligid"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Kaliwang bahagi ng paligid"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Kanang bahagi ng paligid"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"I-expand sa kaliwa at kanang magkahiwalay na mga kontrol"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"I-collapse sa pinag-isang kontrol"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"I-mute ang paligid"</string> @@ -797,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Naka-on - Batay sa mukha"</string> <string name="inline_done_button" msgid="6043094985588909584">"Tapos na"</string> <string name="inline_ok_button" msgid="603075490581280343">"Ilapat"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"I-off ang mga notification"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Naka-silent"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Awtomatiko"</string> @@ -908,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gumamit ng split screen nang nasa kanan ang app"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gumamit ng split screen nang nasa kaliwa ang app"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gamitin ang full screen"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gamitin ang desktop windowing"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Lumipat sa app sa kanan o ibaba habang ginagamit ang split screen"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Lumipat sa app sa kaliwa o itaas habang ginagamit ang split screen"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Habang nasa split screen: magpalit-palit ng app"</string> @@ -1206,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"itago ang kontrol sa media na ito para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Hindi maitatago ang kasalukuyang session ng media."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Itago"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Nagpe-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> ni/ng <xliff:g id="ARTIST_NAME">%2$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sa <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml index 03cca6df05bd..92a122dcf437 100644 --- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Naka-off"</item> <item msgid="4875147066469902392">"Naka-on"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Hindi available"</item> <item msgid="5044688398303285224">"Naka-off"</item> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index eb5b95143af7..a68bc74df470 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Çevredeki sesler"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Sağ"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Çevredeki sesler"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Sol çevredeki sesler"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Sağ çevredeki sesler"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Sol ve sağ kontrolleri ayırarak genişlet"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kontrolleri birleştirerek daralt"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Çevredeki sesleri kapat"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Çevredeki sesleri aç"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Araçlar"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ayarlar"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Not"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonunun engellemesi kaldırılsın mı?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerasının engellemesi kaldırılsın mı?"</string> @@ -517,7 +513,7 @@ <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Ortak eğitimi başlatmak için sola kaydırın"</string> <string name="cta_tile_button_to_open_widget_editor" msgid="3871562362382963878">"Özelleştir"</string> <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Kapat"</string> - <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Burada widget\'larınızı ekleyin, kaldırın ve düzenleyin"</string> + <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Widget ekleyin, kaldırın ve düzenleyin"</string> <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Daha fazla widget ekle"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Açık - Yüze göre"</string> <string name="inline_done_button" msgid="6043094985588909584">"Bitti"</string> <string name="inline_ok_button" msgid="603075490581280343">"Uygula"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirimleri kapat"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Sessiz"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Varsayılan"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatik"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Sağdaki uygulamayla birlikte bölünmüş ekranı kullan"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Soldaki uygulamayla birlikte bölünmüş ekranı kullan"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Tam ekran kullanın"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Masaüstü pencere sistemini kullan"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yap"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran kullanırken soldaki veya üstteki uygulamaya geçiş yapın"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna ekle"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Konum geçersiz."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Konum: <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Hızlı ayar kutusu daha önce eklendi"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kutu eklendi"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kutu kaldırıldı"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> için bu medya kontrolü gizlensin mi?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Geçerli medya oturumu gizlenemez."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizle"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısı çalıyor"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml index 7c17ace16d10..986981f21237 100644 --- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Kapalı"</item> <item msgid="4875147066469902392">"Açık"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Kullanılamıyor"</item> <item msgid="5044688398303285224">"Kapalı"</item> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 1f5d0aac98c6..2e0229393897 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Звуки оточення"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ліворуч"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Праворуч"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Звуки оточення"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Звуки оточення ліворуч"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Звуки оточення праворуч"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Розгорнути в окремі елементи керування ліворуч і праворуч"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Згорнути в єдиний елемент керування"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Вимкнути звуки оточення"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Увімкнути звуки оточення"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменти"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Живі субтитри"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Налаштування"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нотатка"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Надати доступ до камери пристрою?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Увімкнути (за обличчям)"</string> <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string> <string name="inline_ok_button" msgid="603075490581280343">"Застосувати"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Вимкнути сповіщення"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Без звуку"</string> <string name="notification_alert_title" msgid="3656229781017543655">"За умовчанням"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Розділити екран і показувати додаток праворуч"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Розділити екран і показувати додаток ліворуч"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Використовувати повноекранний режим"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Використовувати режим вікон для комп’ютера"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти до додатка праворуч або внизу на розділеному екрані"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Під час розділення екрана перемикатися на додаток ліворуч або вгорі"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додати на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиція недійсна."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плитку вже додано"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Опцію додано"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Опцію вилучено"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор швидких налаштувань."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Приховати цей елемент керування для <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Поточний медіасеанс не можна приховати."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Приховати"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Налаштування"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Пісня \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, грає в додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml index 8b50c085ddb4..a31e858074e0 100644 --- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Вимкнено"</item> <item msgid="4875147066469902392">"Увімкнено"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Недоступно"</item> <item msgid="5044688398303285224">"Вимкнено"</item> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index bcaa91240d53..c5a96096a86b 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"اطراف"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"دائیں"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"بائیں"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"سراؤنڈنگ ساؤنڈ"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"بایاں سراؤنڈنگ ساؤنڈ"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"دایاں سراؤنڈنگ ساؤنڈ"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"بائیں اور دائیں علیحدہ کردہ کنٹرولز کو پھیلائیں"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"یونیفائیڈ کنٹرول کیلئے سکیڑیں"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"اطراف کو خاموش کریں"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"اطراف کی آواز چالو کریں"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ٹولز"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"لائیو کیپشن"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"ترتیبات"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"نوٹ"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"آلے کا مائیکروفون غیر مسدود کریں؟"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"آلے کا کیمرا غیر مسدود کریں؟"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"آن - چہرے پر مبنی"</string> <string name="inline_done_button" msgid="6043094985588909584">"ہو گیا"</string> <string name="inline_ok_button" msgid="603075490581280343">"لاگو کریں"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"اطلاعات کو آف کریں"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"خاموش"</string> <string name="notification_alert_title" msgid="3656229781017543655">"ڈیفالٹ"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"بائیں جانب ایپ کے ساتھ اسپلٹ اسکرین کا استعمال کریں"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"دائیں جانب ایپ کے ساتھ اسپلٹ اسکرین کا استعمال کریں"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"فُل اسکرین استعمال کریں"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ڈیسک ٹاپ ونڈو موڈ استعمال کریں"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"اسپلٹ اسکرین کا استعمال کرتے ہوئے دائیں یا نیچے ایپ پر سوئچ کریں"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"اسپلٹ اسکرین کا استعمال کرتے ہوئے بائیں یا اوپر ایپ پر سوئچ کریں"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"اسپلٹ اسکرین کے دوران: ایک ایپ کو دوسرے سے تبدیل کریں"</string> @@ -1207,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے اس میڈیا کنٹرول کو چھپائیں؟"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"میڈیا کے موجودہ سیشن کو چھپایا نہیں جا سکتا۔"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چل رہا ہے"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml index fea05338be7c..ea032f1451bd 100644 --- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"آف ہے"</item> <item msgid="4875147066469902392">"آن ہے"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"دستیاب نہیں ہے"</item> <item msgid="5044688398303285224">"آف ہے"</item> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index bf070b5535bd..fee0eb9c5473 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Atrof-muhit"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Chap"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Oʻng"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Atrof tovushlari"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Chap tomondan tovushlar"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Oʻng tomondan tovushlar"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Chap va oʻngga ajratilgan boshqaruv elementlariga yoyish"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Yagona boshqaruvga yigʻish"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Atrof-muhitni ovozsiz qilish"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Atrof-muhitni sukutdan chiqarish"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Vositalar"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Jonli izoh"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Sozlamalar"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qayd"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Yoqish - Yuz asosida"</string> <string name="inline_done_button" msgid="6043094985588909584">"Tayyor"</string> <string name="inline_ok_button" msgid="603075490581280343">"Tatbiq etish"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirishnoma kelmasin"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Sokin"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Standart"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Ekranni ajratib, joriy ilovani oʻngga joylash"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Ekranni ajratib, joriy ilovani chapga joylash"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Butun ekrandan foydalanish"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Oynalarni desktop rejimda chiqarish"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ajratilgan ekranda oʻngdagi yoki pastdagi ilovaga almashish"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ajratilgan ekranda chapdagi yoki yuqoridagi ilovaga almashish"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bu joyga kiritish: <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozitsiya yaroqsiz."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Joylashuv: <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Katakcha allaqachon kiritilgan"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Katakcha kiritildi"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Katakcha olib tashlandi"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Tezkor sozlamalar muharriri"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun media boshqaruvi berkitilsinmi?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Joriy media seansi berkitilmadi."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml index 9b8ca80c2fee..1433a9b79071 100644 --- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Oʻchiq"</item> <item msgid="4875147066469902392">"Yoniq"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Ishlamaydi"</item> <item msgid="5044688398303285224">"Oʻchiq"</item> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 9e11f3813842..c79eef76e6e4 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Âm lượng xung quanh"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Trái"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Phải"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Môi trường xung quanh"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Môi trường xung quanh bên trái"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Môi trường xung quanh bên phải"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Mở rộng thành các nút điều khiển tách biệt bên trái và bên phải"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Thu gọn thành nút điều khiển hợp nhất"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Tắt tiếng xung quanh"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Bật tiếng xung quanh"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Công cụ"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Phụ đề trực tiếp"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Cài đặt"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ghi chú"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Bỏ chặn micrô của thiết bị?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn camera của thiết bị?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Đang bật – Dựa trên khuôn mặt"</string> <string name="inline_done_button" msgid="6043094985588909584">"Xong"</string> <string name="inline_ok_button" msgid="603075490581280343">"Áp dụng"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Tắt thông báo"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Im lặng"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Mặc định"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Tự động"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Dùng tính năng chia đôi màn hình với ứng dụng ở bên phải"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Dùng tính năng chia đôi màn hình với ứng dụng ở bên trái"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Dùng chế độ toàn màn hình"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Sử dụng chế độ cửa sổ trên máy tính"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Chuyển sang ứng dụng bên phải hoặc ở dưới khi đang chia đôi màn hình"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Chuyển sang ứng dụng bên trái hoặc ở trên khi đang chia đôi màn hình"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Trong chế độ chia đôi màn hình: thay một ứng dụng bằng ứng dụng khác"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Thêm vào vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Vị trí không hợp lệ."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Đã thêm ô"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Đã thêm thẻ thông tin"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Đã xóa thẻ thông tin"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Trình chỉnh sửa cài đặt nhanh."</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Ẩn tính năng điều khiển này cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Không thể ẩn phiên phát nội dung nghe nhìn hiện tại."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Đang phát <xliff:g id="SONG_NAME">%1$s</xliff:g> của <xliff:g id="ARTIST_NAME">%2$s</xliff:g> trên <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml index afbf477ebcd4..02d2bb6be45f 100644 --- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Đang tắt"</item> <item msgid="4875147066469902392">"Đang bật"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Không hoạt động"</item> <item msgid="5044688398303285224">"Đang tắt"</item> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index cbc4e5183f43..f0f55a827930 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"周围声音"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左侧"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右侧"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"环境音"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"左侧环境音"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"右侧环境音"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"展开为左侧和右侧的单独控件"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收起为统一控件"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"将周围声音静音"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"取消周围声音静音"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"实时字幕"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"设置"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"记事"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解锁设备麦克风吗?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解锁设备摄像头吗?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已开启 - 基于人脸"</string> <string name="inline_done_button" msgid="6043094985588909584">"完成"</string> <string name="inline_ok_button" msgid="603075490581280343">"应用"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"关闭通知"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"静音"</string> <string name="notification_alert_title" msgid="3656229781017543655">"默认"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"自动"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"使用分屏模式,并将应用置于右侧"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"使用分屏模式,并将应用置于左侧"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"使用全屏"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"使用桌面设备窗口化模式"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分屏模式时,切换到右侧或下方的应用"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分屏模式时,切换到左侧或上方的应用"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"在分屏期间:将一个应用替换为另一个应用"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"添加到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置无效。"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"功能块已添加"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已添加功能块"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除功能块"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"要针对“<xliff:g id="APP_NAME">%1$s</xliff:g>”隐藏此媒体控件吗?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"无法隐藏当前的媒体会话。"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隐藏"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml index a3922e5168c9..5980c314d0d6 100644 --- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"已关闭"</item> <item msgid="4875147066469902392">"已开启"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"不可用"</item> <item msgid="5044688398303285224">"已关闭"</item> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 0e1de31e0a08..caac7437b4e0 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境聲音"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"環境"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"左邊環境"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"右邊環境"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"打開就可以分開左右控制"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收埋就可以統一控制"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"環境聲音靜音"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"取消環境聲音靜音"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"設定"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已開啟 - 根據面孔偵測"</string> <string name="inline_done_button" msgid="6043094985588909584">"完成"</string> <string name="inline_ok_button" msgid="603075490581280343">"套用"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"關閉通知"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"靜音"</string> <string name="notification_alert_title" msgid="3656229781017543655">"預設"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"使用分割螢幕,並在右側顯示應用程式"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"使用分割螢幕,並在左側顯示應用程式"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"使用全螢幕"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"使用桌面電腦視窗模式"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割螢幕時,切換至右邊或下方的應用程式"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割螢幕時,切換至左邊或上方的應用程式"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割螢幕期間:更換應用程式"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"加去位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置冇效。"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"已新增資訊方塊"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"加咗圖塊"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"移除咗圖塊"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯工具。"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏此「<xliff:g id="APP_NAME">%1$s</xliff:g>」媒體控制嗎?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在透過 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml index 26bec2c5f0d7..7369d9519b34 100644 --- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"已關閉"</item> <item msgid="4875147066469902392">"已開啟"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"無法使用"</item> <item msgid="5044688398303285224">"已關閉"</item> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index a34333bcbc80..d3a5544ac694 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -423,20 +423,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"環境"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"左側環境"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"右側環境"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"展開為左右獨立控制選項"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收合為統合控制選項"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"將環境靜音"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"取消環境靜音"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"設定"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"解除封鎖裝置相機?"</string> @@ -798,7 +794,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已開啟 - 依臉部方向旋轉"</string> <string name="inline_done_button" msgid="6043094985588909584">"完成"</string> <string name="inline_ok_button" msgid="603075490581280343">"套用"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"關閉通知"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"靜音"</string> <string name="notification_alert_title" msgid="3656229781017543655">"預設"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string> @@ -909,8 +906,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"使用分割畫面,並在右側顯示應用程式"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"使用分割畫面,並在左側顯示應用程式"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"使用全螢幕模式"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"使用電腦視窗化模式"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割畫面時,切換到右邊或上方的應用程式"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割畫面時,切換到左邊或上方的應用程式"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割畫面期間:更換應用程式"</string> @@ -1006,8 +1002,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"新增到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置無效。"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"已新增過該設定方塊"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已新增設定方塊"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除設定方塊"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯器。"</string> @@ -1208,7 +1203,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏「<xliff:g id="APP_NAME">%1$s</xliff:g>」的媒體控制選項嗎?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"系統正透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>,共 <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml index 6e272f213526..18a6d12dcff9 100644 --- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"已關閉"</item> <item msgid="4875147066469902392">"已開啟"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"無法使用"</item> <item msgid="5044688398303285224">"已關閉"</item> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 7d43adc83376..08657d1bfe54 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -425,20 +425,16 @@ <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Izindawo ezizungezile"</string> <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kwesokunxele"</string> <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kwesokudla"</string> - <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) --> - <skip /> - <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) --> - <skip /> + <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Izindawo ezizungezile"</string> + <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Indawo ezungezile engakwesokunxele"</string> + <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Indawo ezungezile engakwesokudla"</string> <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Nwebela ezilawulini ezihlukanisiwe zakwesokunxele nakwesokudla"</string> <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Goqa ezilawulini ezihlanganisiwe"</string> <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Thulisa izindawo ezizungezile"</string> <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Susa ukuthula ezindaweni ezizungezile"</string> <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Amathuluzi"</string> <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okushuthwe Bukhoma"</string> - <!-- no translation found for hearing_devices_settings_button (999474385481812222) --> - <skip /> + <string name="hearing_devices_settings_button" msgid="999474385481812222">"Amasethingi"</string> <string name="quick_settings_notes_label" msgid="1028004078001002623">"Inothi"</string> <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vulela imakrofoni yedivayisi?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vulela ikhamera yedivayisi?"</string> @@ -800,7 +796,8 @@ <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Vuliwe - Kususelwe kubuso"</string> <string name="inline_done_button" msgid="6043094985588909584">"Kwenziwe"</string> <string name="inline_ok_button" msgid="603075490581280343">"Faka"</string> - <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Vala izaziso"</string> + <!-- no translation found for inline_turn_off_notifications (2653064779176881329) --> + <skip /> <string name="notification_silence_title" msgid="8608090968400832335">"Kuthulile"</string> <string name="notification_alert_title" msgid="3656229781017543655">"Okuzenzekelayo"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Okuzenzekelayo"</string> @@ -911,8 +908,7 @@ <string name="system_multitasking_rhs" msgid="8779289852395243004">"Sebenzisa ukuhlukanisa isikrini nge-app kwesokudla"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Sebenzisa ukuhlukanisa isikrini nge-app kwesokunxele"</string> <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Sebenzisa isikrini esigcwele"</string> - <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) --> - <skip /> + <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Sebenzisa iwindi ledeskithophu"</string> <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Shintshela ku-app ngakwesokudla noma ngezansi ngenkathi usebenzisa uhlukanisa isikrini"</string> <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Shintshela ku-app ngakwesokunxele noma ngaphezulu ngenkathi usebenzisa ukuhlukanisa isikrini"</string> <string name="system_multitasking_replace" msgid="7410071959803642125">"Ngesikhathi sokuhlukaniswa kwesikrini: shintsha i-app ngenye"</string> @@ -1008,8 +1004,7 @@ <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engeza kusikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Indawo ayivumelekile."</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Isikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string> - <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) --> - <skip /> + <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Ithayela lifakiwe kakade"</string> <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ithayela lingeziwe"</string> <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ithayela likhishiwe"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Isihleli sezilungiselelo ezisheshayo."</string> @@ -1210,7 +1205,6 @@ <string name="controls_media_close_session" msgid="4780485355795635052">"Fihlela i-<xliff:g id="APP_NAME">%1$s</xliff:g> lesi silawuli semidiya?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Iseshini yamanje yemidiya ayikwazi ukufihlwa."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fihla"</string> - <string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"I-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> idlala kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string> <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ku-<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml index 13ffe042c07e..674aeaa3b890 100644 --- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml @@ -56,6 +56,9 @@ <item msgid="5376619709702103243">"Valiwe"</item> <item msgid="4875147066469902392">"Vuliwe"</item> </string-array> + <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) --> + <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) --> + <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) --> <string-array name="tile_states_flashlight"> <item msgid="3465257127433353857">"Akutholakali"</item> <item msgid="5044688398303285224">"Valiwe"</item> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index f4c6904028ca..15519ff37d0c 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -34,7 +34,7 @@ <!-- Base colors for notification shade/scrim, the alpha component is adjusted programmatically to match the spec --> - <color name="shade_panel_base">@android:color/system_accent1_900</color> + <color name="shade_panel_base">@android:color/system_accent1_100</color> <color name="notification_scrim_base">@android:color/system_accent1_100</color> <!-- Fallback colors for notification shade/scrim --> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index fefc222f283f..3fdb98b4e00b 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1016,6 +1016,13 @@ <string name="hearing_devices_presets_error">Couldn\'t update preset</string> <!-- QuickSettings: Title for hearing aids presets. Preset is a set of hearing aid settings. User can apply different settings in different environments (e.g. Outdoor, Restaurant, Home) [CHAR LIMIT=40]--> <string name="hearing_devices_preset_label">Preset</string> + <!-- QuickSettings: Title for hearing aids input routing control in hearing device dialog. [CHAR LIMIT=40]--> + <string name="hearing_devices_input_routing_label">Default microphone for calls</string> + <!-- QuickSettings: Option for hearing aids input routing control in hearing device dialog. It will alter input routing for calls for hearing aid. [CHAR LIMIT=40]--> + <string-array name="hearing_device_input_routing_options"> + <item>Hearing aid microphone</item> + <item>This phone\'s microphone</item> + </string-array> <!-- QuickSettings: Content description for the icon that indicates the item is selected [CHAR LIMIT=NONE]--> <string name="hearing_devices_spinner_item_selected">Selected</string> <!-- QuickSettings: Title for ambient controls. [CHAR LIMIT=40]--> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt index f276a82baaef..c30580fa01e7 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt @@ -37,51 +37,43 @@ import kotlinx.coroutines.launch * @param operand The [Evaluator.ConditionOperand] to apply to the conditions. */ @OptIn(ExperimentalCoroutinesApi::class) -class CombinedCondition -constructor( +class CombinedCondition( private val scope: CoroutineScope, private val conditions: Collection<Condition>, @Evaluator.ConditionOperand private val operand: Int, ) : Condition(scope, null, false) { - private var job: Job? = null private val _startStrategy by lazy { calculateStartStrategy() } - override fun start() { - job = - scope.launch { - val groupedConditions = conditions.groupBy { it.isOverridingCondition } + override suspend fun start() { + val groupedConditions = conditions.groupBy { it.isOverridingCondition } - lazilyEvaluate( - conditions = groupedConditions.getOrDefault(true, emptyList()), - filterUnknown = true, + lazilyEvaluate( + conditions = groupedConditions.getOrDefault(true, emptyList()), + filterUnknown = true, + ) + .distinctUntilChanged() + .flatMapLatest { overriddenValue -> + // If there are overriding conditions with values set, they take precedence. + if (overriddenValue == null) { + lazilyEvaluate( + conditions = groupedConditions.getOrDefault(false, emptyList()), + filterUnknown = false, ) - .distinctUntilChanged() - .flatMapLatest { overriddenValue -> - // If there are overriding conditions with values set, they take precedence. - if (overriddenValue == null) { - lazilyEvaluate( - conditions = groupedConditions.getOrDefault(false, emptyList()), - filterUnknown = false, - ) - } else { - flowOf(overriddenValue) - } - } - .collect { conditionMet -> - if (conditionMet == null) { - clearCondition() - } else { - updateCondition(conditionMet) - } - } + } else { + flowOf(overriddenValue) + } + } + .collect { conditionMet -> + if (conditionMet == null) { + clearCondition() + } else { + updateCondition(conditionMet) + } } } - override fun stop() { - job?.cancel() - job = null - } + override fun stop() {} /** * Evaluates a list of conditions lazily with support for short-circuiting. Conditions are diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt index 69236b48ed51..44803bd22b45 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt @@ -22,6 +22,8 @@ import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import java.lang.ref.WeakReference import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch /** * Base class for a condition that needs to be fulfilled in order for [Monitor] to inform its @@ -43,11 +45,12 @@ protected constructor( ) { private val mTag: String = javaClass.simpleName - private val _callbacks = mutableListOf<WeakReference<Callback>>() - private var _started = false + private val callbacks = mutableListOf<WeakReference<Callback>>() + private var started = false + private var currentJob: Job? = null /** Starts monitoring the condition. */ - protected abstract fun start() + protected abstract suspend fun start() /** Stops monitoring the condition. */ protected abstract fun stop() @@ -64,21 +67,21 @@ protected constructor( */ fun addCallback(callback: Callback) { if (shouldLog()) Log.d(mTag, "adding callback") - _callbacks.add(WeakReference(callback)) + callbacks.add(WeakReference(callback)) - if (_started) { + if (started) { callback.onConditionChanged(this) return } - start() - _started = true + currentJob = _scope.launch { start() } + started = true } /** Removes the provided callback from further receiving updates. */ fun removeCallback(callback: Callback) { if (shouldLog()) Log.d(mTag, "removing callback") - val iterator = _callbacks.iterator() + val iterator = callbacks.iterator() while (iterator.hasNext()) { val cb = iterator.next().get() if (cb == null || cb === callback) { @@ -86,12 +89,15 @@ protected constructor( } } - if (_callbacks.isNotEmpty() || !_started) { + if (callbacks.isNotEmpty() || !started) { return } stop() - _started = false + currentJob?.cancel() + currentJob = null + + started = false } /** @@ -151,7 +157,7 @@ protected constructor( } private fun sendUpdate() { - val iterator = _callbacks.iterator() + val iterator = callbacks.iterator() while (iterator.hasNext()) { val cb = iterator.next().get() if (cb == null) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt index 0f535cdfa5cc..849b3d6d8d8b 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt @@ -19,7 +19,7 @@ fun Flow<Boolean>.toCondition( return object : Condition(scope, initialValue, false) { var job: Job? = null - override fun start() { + override suspend fun start() { job = scope.launch { collect { updateCondition(it) } } } diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index c78f75a334fd..089466707298 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -894,8 +894,8 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { if (NotificationBundleUi.isEnabled()) { return enr.getEntryAdapter().canDragAndDrop(); } else { - boolean canBubble = enr.getEntry().canBubble(); - Notification notif = enr.getEntry().getSbn().getNotification(); + boolean canBubble = enr.getEntryLegacy().canBubble(); + Notification notif = enr.getEntryLegacy().getSbn().getNotification(); PendingIntent dragIntent = notif.contentIntent != null ? notif.contentIntent : notif.fullScreenIntent; if (dragIntent != null && dragIntent.isActivity() && !canBubble) { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java index fb3bc620ee68..14b13d105482 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java @@ -121,6 +121,13 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, private Spinner mPresetSpinner; private HearingDevicesPresetsController mPresetController; private HearingDevicesSpinnerAdapter mPresetInfoAdapter; + + private View mInputRoutingLayout; + private Spinner mInputRoutingSpinner; + private HearingDevicesInputRoutingController.Factory mInputRoutingControllerFactory; + private HearingDevicesInputRoutingController mInputRoutingController; + private HearingDevicesSpinnerAdapter mInputRoutingAdapter; + private final HearingDevicesPresetsController.PresetCallback mPresetCallback = new HearingDevicesPresetsController.PresetCallback() { @Override @@ -169,7 +176,8 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, @Background Executor bgExecutor, AudioManager audioManager, HearingDevicesUiEventLogger uiEventLogger, - QSSettingsPackageRepository qsSettingsPackageRepository) { + QSSettingsPackageRepository qsSettingsPackageRepository, + HearingDevicesInputRoutingController.Factory inputRoutingControllerFactory) { mShowPairNewDevice = showPairNewDevice; mSystemUIDialogFactory = systemUIDialogFactory; mActivityStarter = activityStarter; @@ -182,6 +190,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mUiEventLogger = uiEventLogger; mLaunchSourceId = launchSourceId; mQSSettingsPackageRepository = qsSettingsPackageRepository; + mInputRoutingControllerFactory = inputRoutingControllerFactory; } @Override @@ -239,6 +248,12 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mPresetLayout.setVisibility( mPresetController.isPresetControlAvailable() ? VISIBLE : GONE); } + if (mInputRoutingController != null) { + mInputRoutingController.setDevice(device); + mInputRoutingController.isInputRoutingControlAvailable( + available -> mMainExecutor.execute(() -> mInputRoutingLayout.setVisibility( + available ? VISIBLE : GONE))); + } if (mAmbientController != null) { mAmbientController.loadDevice(device); } @@ -310,6 +325,11 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, setupDeviceListView(dialog, hearingDeviceItemList); setupPairNewDeviceButton(dialog); setupPresetSpinner(dialog, activeHearingDevice); + if (com.android.settingslib.flags.Flags.hearingDevicesInputRoutingControl() + && com.android.systemui.Flags + .hearingDevicesInputRoutingUiImprovement()) { + setupInputRoutingSpinner(dialog, activeHearingDevice); + } if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) { setupAmbientControls(activeHearingDevice); } @@ -383,6 +403,52 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mBgExecutor.execute(() -> mPresetController.registerHapCallback()); } + private void setupInputRoutingSpinner(SystemUIDialog dialog, + CachedBluetoothDevice activeHearingDevice) { + mInputRoutingController = mInputRoutingControllerFactory.create(dialog.getContext()); + mInputRoutingController.setDevice(activeHearingDevice); + + mInputRoutingSpinner = dialog.requireViewById(R.id.input_routing_spinner); + mInputRoutingAdapter = new HearingDevicesSpinnerAdapter(dialog.getContext()); + mInputRoutingAdapter.addAll( + HearingDevicesInputRoutingController.getInputRoutingOptions(dialog.getContext())); + mInputRoutingSpinner.setAdapter(mInputRoutingAdapter); + // Disable redundant Touch & Hold accessibility action for Switch Access + mInputRoutingSpinner.setAccessibilityDelegate(new View.AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo(@NonNull View host, + @NonNull AccessibilityNodeInfo info) { + info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK); + super.onInitializeAccessibilityNodeInfo(host, info); + } + }); + // Should call setSelection(index, false) for the spinner before setOnItemSelectedListener() + // to avoid extra onItemSelected() get called when first register the listener. + final int initialPosition = + mInputRoutingController.getUserPreferredInputRoutingValue(); + mInputRoutingSpinner.setSelection(initialPosition, false); + mInputRoutingAdapter.setSelected(initialPosition); + mInputRoutingSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + mInputRoutingAdapter.setSelected(position); + mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_INPUT_ROUTING_SELECT, + mLaunchSourceId); + mInputRoutingController.selectInputRouting(position); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + // Do nothing + } + }); + + mInputRoutingLayout = dialog.requireViewById(R.id.input_routing_layout); + mInputRoutingController.isInputRoutingControlAvailable( + available -> mMainExecutor.execute(() -> mInputRoutingLayout.setVisibility( + available ? VISIBLE : GONE))); + } + private void setupAmbientControls(CachedBluetoothDevice activeHearingDevice) { final AmbientVolumeLayout ambientLayout = mDialog.requireViewById(R.id.ambient_layout); ambientLayout.setUiEventLogger(mUiEventLogger, mLaunchSourceId); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingController.kt b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingController.kt new file mode 100644 index 000000000000..e8fa7ba2268b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingController.kt @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2025 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.accessibility.hearingaid + +import android.content.Context +import android.media.AudioManager +import android.util.Log +import androidx.collection.ArraySet +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.HapClientProfile +import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants +import com.android.settingslib.bluetooth.HearingAidAudioRoutingHelper +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.res.R +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * The controller of the hearing device input routing. + * + * <p> It manages and update the input routing according to the value. + */ +open class HearingDevicesInputRoutingController +@AssistedInject +constructor( + @Assisted context: Context, + private val audioManager: AudioManager, + @Background private val backgroundDispatcher: CoroutineDispatcher, +) { + private val audioRoutingHelper = HearingAidAudioRoutingHelper(context) + private var cachedDevice: CachedBluetoothDevice? = null + private val bgCoroutineScope = CoroutineScope(backgroundDispatcher) + + /** Factory to create a [HearingDevicesInputRoutingController] instance. */ + @AssistedFactory + interface Factory { + fun create(context: Context): HearingDevicesInputRoutingController + } + + /** Possible input routing UI. Need to align with [getInputRoutingOptions] */ + enum class InputRoutingValue { + HEARING_DEVICE, + BUILTIN_MIC, + } + + companion object { + private const val TAG = "HearingDevicesInputRoutingController" + + /** Gets input routing options as strings. */ + @JvmStatic + fun getInputRoutingOptions(context: Context): Array<String> { + return context.resources.getStringArray(R.array.hearing_device_input_routing_options) + } + } + + fun interface InputRoutingControlAvailableCallback { + fun onResult(available: Boolean) + } + + /** + * Sets the device for this controller to control the input routing. + * + * @param device the [CachedBluetoothDevice] set to the controller + */ + fun setDevice(device: CachedBluetoothDevice?) { + this@HearingDevicesInputRoutingController.cachedDevice = device + } + + fun isInputRoutingControlAvailable(callback: InputRoutingControlAvailableCallback) { + bgCoroutineScope.launch { + val result = isInputRoutingControlAvailableInternal() + callback.onResult(result) + } + } + + /** + * Checks if input routing control is available for the currently set device. + * + * @return `true` if input routing control is available. + */ + private suspend fun isInputRoutingControlAvailableInternal(): Boolean { + val device = cachedDevice ?: return false + + val memberDevices = device.memberDevice + + val inputInfos = + withContext(backgroundDispatcher) { + audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS) + } + val supportedInputDeviceAddresses = ArraySet<String>() + supportedInputDeviceAddresses.add(device.address) + if (memberDevices.isNotEmpty()) { + memberDevices.forEach { supportedInputDeviceAddresses.add(it.address) } + } + + val isValidInputDevice = + inputInfos.any { supportedInputDeviceAddresses.contains(it.address) } + // Not support ASHA hearing device for input routing feature + val isHapHearingDevice = device.profiles.any { profile -> profile is HapClientProfile } + + if (isHapHearingDevice && !isValidInputDevice) { + Log.d(TAG, "Not supported input type hearing device.") + } + return isHapHearingDevice && isValidInputDevice + } + + /** Gets the user's preferred [InputRoutingValue]. */ + fun getUserPreferredInputRoutingValue(): Int { + val device = cachedDevice ?: return InputRoutingValue.HEARING_DEVICE.ordinal + + return if (device.device.isMicrophonePreferredForCalls) { + InputRoutingValue.HEARING_DEVICE.ordinal + } else { + InputRoutingValue.BUILTIN_MIC.ordinal + } + } + + /** + * Sets the input routing to [android.bluetooth.BluetoothDevice.setMicrophonePreferredForCalls] + * based on the input routing index. + * + * @param inputRoutingIndex The desired input routing index. + */ + fun selectInputRouting(inputRoutingIndex: Int) { + val device = cachedDevice ?: return + + val useBuiltinMic = (inputRoutingIndex == InputRoutingValue.BUILTIN_MIC.ordinal) + val status = + audioRoutingHelper.setPreferredInputDeviceForCalls( + device, + if (useBuiltinMic) HearingAidAudioRoutingConstants.RoutingValue.BUILTIN_DEVICE + else HearingAidAudioRoutingConstants.RoutingValue.AUTO, + ) + if (!status) { + Log.d(TAG, "Fail to configure setPreferredInputDeviceForCalls") + } + setMicrophonePreferredForCallsForDeviceSet(device, !useBuiltinMic) + } + + private fun setMicrophonePreferredForCallsForDeviceSet( + device: CachedBluetoothDevice?, + enabled: Boolean, + ) { + device ?: return + device.device.isMicrophonePreferredForCalls = enabled + val memberDevices = device.memberDevice + if (memberDevices.isNotEmpty()) { + memberDevices.forEach { d -> d.device.isMicrophonePreferredForCalls = enabled } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt index 4a695d638713..82ac10d85e70 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt +++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt @@ -40,6 +40,8 @@ enum class HearingDevicesUiEvent(private val id: Int) : UiEventLogger.UiEventEnu HEARING_DEVICES_AMBIENT_EXPAND_CONTROLS(2153), @UiEvent(doc = "Collapse the ambient volume controls") HEARING_DEVICES_AMBIENT_COLLAPSE_CONTROLS(2154), + @UiEvent(doc = "Select a input routing option from input routing spinner") + HEARING_DEVICES_INPUT_ROUTING_SELECT(2155), @UiEvent(doc = "Click on the device settings to enter hearing devices page") HEARING_DEVICES_SETTINGS_CLICK(2172); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt index fb47d429e271..e25d54bd38d3 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt +++ b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt @@ -29,40 +29,40 @@ import com.android.systemui.qs.tiles.HearingDevicesTile import com.android.systemui.qs.tiles.NightDisplayTile import com.android.systemui.qs.tiles.OneHandedModeTile import com.android.systemui.qs.tiles.ReduceBrightColorsTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.impl.colorcorrection.domain.ColorCorrectionTileMapper +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel import com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor.ColorCorrectionTileDataInteractor import com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor.ColorCorrectionUserActionInteractor import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel -import com.android.systemui.qs.tiles.impl.fontscaling.domain.FontScalingTileMapper +import com.android.systemui.qs.tiles.impl.colorcorrection.ui.mapper.ColorCorrectionTileMapper import com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor.FontScalingTileDataInteractor import com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor.FontScalingTileUserActionInteractor import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel -import com.android.systemui.qs.tiles.impl.hearingdevices.domain.HearingDevicesTileMapper +import com.android.systemui.qs.tiles.impl.fontscaling.ui.mapper.FontScalingTileMapper import com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor.HearingDevicesTileDataInteractor import com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor.HearingDevicesTileUserActionInteractor import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel -import com.android.systemui.qs.tiles.impl.inversion.domain.ColorInversionTileMapper +import com.android.systemui.qs.tiles.impl.hearingdevices.ui.mapper.HearingDevicesTileMapper import com.android.systemui.qs.tiles.impl.inversion.domain.interactor.ColorInversionTileDataInteractor import com.android.systemui.qs.tiles.impl.inversion.domain.interactor.ColorInversionUserActionInteractor import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel +import com.android.systemui.qs.tiles.impl.inversion.ui.mapper.ColorInversionTileMapper import com.android.systemui.qs.tiles.impl.night.domain.interactor.NightDisplayTileDataInteractor import com.android.systemui.qs.tiles.impl.night.domain.interactor.NightDisplayTileUserActionInteractor import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel -import com.android.systemui.qs.tiles.impl.night.ui.NightDisplayTileMapper +import com.android.systemui.qs.tiles.impl.night.ui.mapper.NightDisplayTileMapper import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileDataInteractor import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileUserActionInteractor import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel -import com.android.systemui.qs.tiles.impl.onehanded.ui.OneHandedModeTileMapper +import com.android.systemui.qs.tiles.impl.onehanded.ui.mapper.OneHandedModeTileMapper import com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor.ReduceBrightColorsTileDataInteractor import com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor.ReduceBrightColorsTileUserActionInteractor import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel -import com.android.systemui.qs.tiles.impl.reducebrightness.ui.ReduceBrightColorsTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.impl.reducebrightness.ui.mapper.ReduceBrightColorsTileMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt index 831bc1da5a79..26d5562a3b30 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt +++ b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt @@ -5,15 +5,15 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.tiles.BatterySaverTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileDataInteractor import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileUserActionInteractor import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel -import com.android.systemui.qs.tiles.impl.battery.ui.BatterySaverTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.impl.battery.ui.mapper.BatterySaverTileMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module @@ -63,7 +63,7 @@ interface BatterySaverModule { factory: QSTileViewModelFactory.Static<BatterySaverTileModel>, mapper: BatterySaverTileMapper, stateInteractor: BatterySaverTileDataInteractor, - userActionInteractor: BatterySaverTileUserActionInteractor + userActionInteractor: BatterySaverTileUserActionInteractor, ): QSTileViewModel = factory.create( TileSpec.create(BATTERY_SAVER_TILE_SPEC), diff --git a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt index 9db7b50905f8..1301fb87069e 100644 --- a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt @@ -17,9 +17,9 @@ package com.android.systemui.common.domain.interactor import android.util.Log +import com.android.app.displaylib.PerDisplayRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.display.data.repository.DisplayRepository -import com.android.systemui.display.data.repository.PerDisplayRepository import com.android.systemui.model.StateChange import com.android.systemui.model.SysUiState import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java deleted file mode 100644 index 4be9601f4277..000000000000 --- a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2024 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.communal; - -import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; - -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.keyguard.WakefulnessLifecycle; -import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; -import com.android.systemui.keyguard.shared.model.DozeStateModel; -import com.android.systemui.shared.condition.Condition; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.util.kotlin.JavaAdapter; - -import kotlinx.coroutines.CoroutineScope; -import kotlinx.coroutines.Job; - -import javax.inject.Inject; - -/** - * Condition which estimates device inactivity in order to avoid launching a full-screen activity - * while the user is actively using the device. - */ -public class DeviceInactiveCondition extends Condition { - private final KeyguardStateController mKeyguardStateController; - private final WakefulnessLifecycle mWakefulnessLifecycle; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final KeyguardInteractor mKeyguardInteractor; - private final JavaAdapter mJavaAdapter; - private Job mAnyDozeListenerJob; - private boolean mAnyDoze; - private final KeyguardStateController.Callback mKeyguardStateCallback = - new KeyguardStateController.Callback() { - @Override - public void onKeyguardShowingChanged() { - updateState(); - } - }; - private final WakefulnessLifecycle.Observer mWakefulnessObserver = - new WakefulnessLifecycle.Observer() { - @Override - public void onStartedGoingToSleep() { - updateState(); - } - }; - private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onDreamingStateChanged(boolean dreaming) { - updateState(); - } - }; - - @Inject - public DeviceInactiveCondition(@Application CoroutineScope scope, - KeyguardStateController keyguardStateController, - WakefulnessLifecycle wakefulnessLifecycle, KeyguardUpdateMonitor keyguardUpdateMonitor, - KeyguardInteractor keyguardInteractor, JavaAdapter javaAdapter) { - super(scope); - mKeyguardStateController = keyguardStateController; - mWakefulnessLifecycle = wakefulnessLifecycle; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mKeyguardInteractor = keyguardInteractor; - mJavaAdapter = javaAdapter; - } - - @Override - protected void start() { - updateState(); - mKeyguardStateController.addCallback(mKeyguardStateCallback); - mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback); - mWakefulnessLifecycle.addObserver(mWakefulnessObserver); - mAnyDozeListenerJob = mJavaAdapter.alwaysCollectFlow( - mKeyguardInteractor.getDozeTransitionModel(), dozeModel -> { - mAnyDoze = !DozeStateModel.Companion.isDozeOff(dozeModel.getTo()); - updateState(); - }); - } - - @Override - protected void stop() { - mKeyguardStateController.removeCallback(mKeyguardStateCallback); - mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback); - mWakefulnessLifecycle.removeObserver(mWakefulnessObserver); - mAnyDozeListenerJob.cancel(null); - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } - - private void updateState() { - final boolean asleep = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP; - // Doze/AoD is also a dream, but we should never override it with low light as to the user - // it's totally unrelated. - updateCondition(!mAnyDoze && (asleep || mKeyguardStateController.isShowing() - || mKeyguardUpdateMonitor.isDreaming())); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.kt b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.kt new file mode 100644 index 000000000000..70dce2ef0cac --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.kt @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2024 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.communal + +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff +import com.android.systemui.keyguard.shared.model.DozeTransitionModel +import com.android.systemui.shared.condition.Condition +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.util.kotlin.JavaAdapter +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +/** + * Condition which estimates device inactivity in order to avoid launching a full-screen activity + * while the user is actively using the device. + */ +class DeviceInactiveCondition +@Inject +constructor( + @Application private val applicationScope: CoroutineScope, + @Background backgroundScope: CoroutineScope, + private val keyguardStateController: KeyguardStateController, + private val wakefulnessLifecycle: WakefulnessLifecycle, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val keyguardInteractor: KeyguardInteractor, + private val javaAdapter: JavaAdapter, +) : Condition(backgroundScope) { + private var anyDozeListenerJob: Job? = null + private var anyDoze = false + private val keyguardStateCallback: KeyguardStateController.Callback = + object : KeyguardStateController.Callback { + override fun onKeyguardShowingChanged() { + updateState() + } + } + private val wakefulnessObserver: WakefulnessLifecycle.Observer = + object : WakefulnessLifecycle.Observer { + override fun onStartedGoingToSleep() { + updateState() + } + } + private val keyguardUpdateCallback: KeyguardUpdateMonitorCallback = + object : KeyguardUpdateMonitorCallback() { + override fun onDreamingStateChanged(dreaming: Boolean) { + updateState() + } + } + + override suspend fun start() { + updateState() + keyguardStateController.addCallback(keyguardStateCallback) + + // Keyguard update monitor callbacks must be registered on the main thread + applicationScope.launch { keyguardUpdateMonitor.registerCallback(keyguardUpdateCallback) } + wakefulnessLifecycle.addObserver(wakefulnessObserver) + anyDozeListenerJob = + javaAdapter.alwaysCollectFlow(keyguardInteractor.dozeTransitionModel) { + dozeModel: DozeTransitionModel -> + anyDoze = !isDozeOff(dozeModel.to) + updateState() + } + } + + override fun stop() { + keyguardStateController.removeCallback(keyguardStateCallback) + keyguardUpdateMonitor.removeCallback(keyguardUpdateCallback) + wakefulnessLifecycle.removeObserver(wakefulnessObserver) + anyDozeListenerJob?.cancel(null) + } + + override val startStrategy: Int + get() = START_EAGERLY + + private fun updateState() { + val asleep = wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP + // Doze/AoD is also a dream, but we should never override it with low light as to the user + // it's totally unrelated. + updateCondition( + !anyDoze && + (asleep || keyguardStateController.isShowing || keyguardUpdateMonitor.isDreaming) + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt index 6f688d172843..42a345b7deb4 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt @@ -32,6 +32,7 @@ import com.android.systemui.communal.data.model.SuppressionReason import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryModule.Companion.DEFAULT_BACKGROUND_TYPE import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.WhenToDream +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -64,6 +65,12 @@ interface CommunalSettingsRepository { */ fun getWhenToDreamState(user: UserInfo): Flow<WhenToDream> + /** + * Returns a[WhenToStartHub] for the specified user, indicating what state the device should be + * in to automatically display the hub. + */ + fun getWhenToStartHubState(user: UserInfo): Flow<WhenToStartHub> + /** Returns whether glanceable hub is enabled by the current user. */ fun getSettingEnabledByUser(user: UserInfo): Flow<Boolean> @@ -124,6 +131,10 @@ constructor( resources.getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault) } + private val whenToStartHubByDefault by lazy { + resources.getInteger(com.android.internal.R.integer.config_whenToStartHubModeDefault) + } + private val _suppressionReasons = MutableStateFlow<List<SuppressionReason>>( // Suppress hub by default until we get an initial update. @@ -195,6 +206,31 @@ constructor( } .flowOn(bgDispatcher) + override fun getWhenToStartHubState(user: UserInfo): Flow<WhenToStartHub> = + secureSettings + .observerFlow( + userId = user.id, + names = arrayOf(Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB), + ) + .emitOnStart() + .map { + when ( + secureSettings.getIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + whenToStartHubByDefault, + user.id, + ) + ) { + Settings.Secure.GLANCEABLE_HUB_START_NEVER -> WhenToStartHub.NEVER + Settings.Secure.GLANCEABLE_HUB_START_CHARGING -> WhenToStartHub.WHILE_CHARGING + Settings.Secure.GLANCEABLE_HUB_START_CHARGING_UPRIGHT -> + WhenToStartHub.WHILE_CHARGING_AND_POSTURED + Settings.Secure.GLANCEABLE_HUB_START_DOCKED -> WhenToStartHub.WHILE_DOCKED + else -> WhenToStartHub.NEVER + } + } + .flowOn(bgDispatcher) + override fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> = broadcastDispatcher .broadcastFlow( diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt index 51df3338a18e..20bfabdc5fb9 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt @@ -22,7 +22,7 @@ import com.android.systemui.communal.data.model.FEATURE_AUTO_OPEN import com.android.systemui.communal.data.model.FEATURE_MANUAL_OPEN import com.android.systemui.communal.data.model.SuppressionReason import com.android.systemui.communal.posturing.domain.interactor.PosturingInteractor -import com.android.systemui.communal.shared.model.WhenToDream +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dock.DockManager @@ -49,17 +49,17 @@ constructor( @Named(SWIPE_TO_HUB) private val allowSwipeAlways: Boolean, ) { val shouldAutoOpen: Flow<Boolean> = - communalSettingsInteractor.whenToDream - .flatMapLatestConflated { whenToDream -> - when (whenToDream) { - WhenToDream.WHILE_CHARGING -> batteryInteractor.isDevicePluggedIn - WhenToDream.WHILE_DOCKED -> { + communalSettingsInteractor.whenToStartHub + .flatMapLatestConflated { whenToStartHub -> + when (whenToStartHub) { + WhenToStartHub.WHILE_CHARGING -> batteryInteractor.isDevicePluggedIn + WhenToStartHub.WHILE_DOCKED -> { allOf(batteryInteractor.isDevicePluggedIn, dockManager.retrieveIsDocked()) } - WhenToDream.WHILE_POSTURED -> { + WhenToStartHub.WHILE_CHARGING_AND_POSTURED -> { allOf(batteryInteractor.isDevicePluggedIn, posturingInteractor.postured) } - WhenToDream.NEVER -> flowOf(false) + WhenToStartHub.NEVER -> flowOf(false) } } .flowOn(backgroundContext) diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt index 0d7a2d9707d7..cf51fa1b61fb 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt @@ -17,7 +17,6 @@ package com.android.systemui.communal.domain.interactor import android.content.pm.UserInfo -import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import com.android.systemui.communal.data.model.FEATURE_AUTO_OPEN import com.android.systemui.communal.data.model.FEATURE_ENABLED import com.android.systemui.communal.data.model.FEATURE_MANUAL_OPEN @@ -25,10 +24,12 @@ import com.android.systemui.communal.data.model.SuppressionReason import com.android.systemui.communal.data.repository.CommunalSettingsRepository import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.WhenToDream +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserTracker import com.android.systemui.user.domain.interactor.SelectedUserInteractor +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import java.util.concurrent.Executor import javax.inject.Inject @@ -79,6 +80,12 @@ constructor( repository.getWhenToDreamState(user) } + /** When to automatically start hub for the currently selected user. */ + val whenToStartHub: Flow<WhenToStartHub> = + userInteractor.selectedUserInfo.flatMapLatest { user -> + repository.getWhenToStartHubState(user) + } + /** Whether communal hub is allowed by device policy for the current user */ val allowedForCurrentUserByDevicePolicy: Flow<Boolean> = userInteractor.selectedUserInfo.flatMapLatestConflated { user -> diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt new file mode 100644 index 000000000000..be89fda01009 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 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.communal.shared.model + +enum class WhenToStartHub { + NEVER, + WHILE_CHARGING, + WHILE_CHARGING_AND_POSTURED, + WHILE_DOCKED, +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt index 06a14eaa5c85..440c3001a2f9 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt @@ -16,6 +16,7 @@ package com.android.systemui.communal.widgets +import android.appwidget.AppWidgetProviderInfo import com.android.systemui.CoreStartable import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor @@ -101,6 +102,7 @@ constructor( val (_, isActive) = withPrev // The validation is performed once the hub becomes active. if (isActive) { + removeNotLockscreenWidgets(widgets) validateWidgetsAndDeleteOrphaned(widgets) } } @@ -144,6 +146,19 @@ constructor( } } + private fun removeNotLockscreenWidgets(widgets: List<CommunalWidgetContentModel>) { + widgets + .filter { widget -> + when (widget) { + is CommunalWidgetContentModel.Available -> + widget.providerInfo.widgetCategory and + AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD != 0 + else -> false + } + } + .onEach { widget -> communalInteractor.deleteWidget(id = widget.appWidgetId) } + } + /** * Ensure the existence of all associated users for widgets, and remove widgets belonging to * users who have been deleted. diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt index 037b6facc50d..ba9f52b63d41 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt @@ -51,8 +51,9 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.tiles.DeviceControlsTile -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.res.R import dagger.Binds import dagger.BindsOptionalOf import dagger.Module @@ -91,8 +92,8 @@ abstract class ControlsModule { tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC), uiConfig = QSTileUIConfig.Resource( - iconRes = com.android.systemui.res.R.drawable.controls_icon, - labelRes = com.android.systemui.res.R.string.quick_controls_title + iconRes = R.drawable.controls_icon, + labelRes = R.string.quick_controls_title, ), instanceId = uiEventLogger.getNewInstanceId(), category = TileCategory.UTILITIES, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt index 39708a743c23..3520439fda88 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt @@ -16,9 +16,9 @@ package com.android.systemui.dagger -import com.android.systemui.display.data.repository.DefaultDisplayOnlyInstanceRepositoryImpl -import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl -import com.android.systemui.display.data.repository.PerDisplayRepository +import com.android.app.displaylib.DefaultDisplayOnlyInstanceRepositoryImpl +import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl +import com.android.app.displaylib.PerDisplayRepository import com.android.systemui.model.SysUIStateInstanceProvider import com.android.systemui.model.SysUiState import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index f08126af0a7a..edee64e50b53 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -65,7 +65,7 @@ import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.demomode.dagger.DemoModeModule; import com.android.systemui.deviceentry.DeviceEntryModule; import com.android.systemui.display.DisplayModule; -import com.android.systemui.display.data.repository.PerDisplayRepository; +import com.android.app.displaylib.PerDisplayRepository; import com.android.systemui.doze.dagger.DozeComponent; import com.android.systemui.dreams.dagger.DreamModule; import com.android.systemui.flags.FeatureFlags; @@ -97,11 +97,11 @@ import com.android.systemui.plugins.BcSmartspaceConfigPlugin; import com.android.systemui.plugins.BcSmartspaceDataPlugin; import com.android.systemui.privacy.PrivacyModule; import com.android.systemui.process.condition.SystemProcessCondition; -import com.android.systemui.qrcodescanner.dagger.QRCodeScannerModule; import com.android.systemui.qs.FgsManagerController; import com.android.systemui.qs.FgsManagerControllerImpl; import com.android.systemui.qs.QSFragmentStartableModule; import com.android.systemui.qs.footer.dagger.FooterActionsModule; +import com.android.systemui.qs.tiles.impl.qr.ui.model.QRCodeScannerModule; import com.android.systemui.recents.Recents; import com.android.systemui.recordissue.RecordIssueModule; import com.android.systemui.retail.RetailModeModule; diff --git a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt index f3316958f01d..908d0aafb2b9 100644 --- a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt +++ b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt @@ -18,7 +18,9 @@ package com.android.systemui.display import android.hardware.display.DisplayManager import android.os.Handler +import com.android.app.displaylib.DisplayLibBackground import com.android.app.displaylib.DisplayLibComponent +import com.android.app.displaylib.PerDisplayRepository import com.android.app.displaylib.createDisplayLibComponent import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton @@ -34,7 +36,6 @@ import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepos import com.android.systemui.display.data.repository.FocusedDisplayRepository import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl import com.android.systemui.display.data.repository.PerDisplayRepoDumpHelper -import com.android.systemui.display.data.repository.PerDisplayRepository import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractorImpl import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractorModule @@ -85,6 +86,10 @@ interface DisplayModule { @Binds fun dumpRegistrationLambda(helper: PerDisplayRepoDumpHelper): PerDisplayRepository.InitCallback + @Binds + @DisplayLibBackground + fun bindDisplayLibBackground(@Background bgScope: CoroutineScope): CoroutineScope + companion object { @Provides @SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt index a56710ee3772..86c9d84c27b1 100644 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt @@ -16,6 +16,9 @@ package com.android.systemui.display.data.repository +import com.android.app.displaylib.PerDisplayRepository + +// TODO b/401305290 - move to displaylib class FakePerDisplayRepository<T> : PerDisplayRepository<T> { private val instances = mutableMapOf<Int, T>() diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt index 212d55612935..efbae5d04caf 100644 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt @@ -16,6 +16,7 @@ package com.android.systemui.display.data.repository +import com.android.app.displaylib.PerDisplayRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.dump.DumpableFromToString diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt deleted file mode 100644 index 7e00c60dc43a..000000000000 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2025 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.display.data.repository - -import android.util.Log -import android.view.Display -import com.android.app.tracing.coroutines.launchTraced as launch -import com.android.app.tracing.traceSection -import com.android.systemui.dagger.qualifiers.Background -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject -import java.util.concurrent.ConcurrentHashMap -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.collectLatest - -/** - * Used to create instances of type `T` for a specific display. - * - * This is useful for resources or objects that need to be managed independently for each connected - * display (e.g., UI state, rendering contexts, or display-specific configurations). - * - * Note that in most cases this can be implemented by a simple `@AssistedFactory` with `displayId` - * parameter - * - * ```kotlin - * class SomeType @AssistedInject constructor(@Assisted displayId: Int,..) - * @AssistedFactory - * interface Factory { - * fun create(displayId: Int): SomeType - * } - * } - * ``` - * - * Then it can be used to create a [PerDisplayRepository] as follows: - * ```kotlin - * // Injected: - * val repositoryFactory: PerDisplayRepositoryImpl.Factory - * val instanceFactory: PerDisplayRepositoryImpl.Factory - * // repository creation: - * repositoryFactory.create(instanceFactory::create) - * ``` - * - * @see PerDisplayRepository For how to retrieve and manage instances created by this factory. - */ -fun interface PerDisplayInstanceProvider<T> { - /** Creates an instance for a display. */ - fun createInstance(displayId: Int): T? -} - -/** - * Extends [PerDisplayInstanceProvider], adding support for destroying the instance. - * - * This is useful for releasing resources associated with a display when it is disconnected or when - * the per-display instance is no longer needed. - */ -interface PerDisplayInstanceProviderWithTeardown<T> : PerDisplayInstanceProvider<T> { - /** Destroys a previously created instance of `T` forever. */ - fun destroyInstance(instance: T) -} - -/** - * Provides access to per-display instances of type `T`. - * - * Acts as a repository, managing the caching and retrieval of instances created by a - * [PerDisplayInstanceProvider]. It ensures that only one instance of `T` exists per display ID. - */ -interface PerDisplayRepository<T> { - /** Gets the cached instance or create a new one for a given display. */ - operator fun get(displayId: Int): T? - - /** Debug name for this repository, mainly for tracing and logging. */ - val debugName: String - - /** - * Callback to run when a given repository is initialized. - * - * This allows the caller to perform custom logic when the repository is ready to be used, e.g. - * register to dumpManager. - * - * Note that the instance is *leaked* outside of this class, so it should only be done when - * repository is meant to live as long as the caller. In systemUI this is ok because the - * repository lives as long as the process itself. - */ - interface InitCallback { - fun onInit(debugName: String, instance: Any) - } -} - -/** - * Default implementation of [PerDisplayRepository]. - * - * This class manages a cache of per-display instances of type `T`, creating them using a provided - * [PerDisplayInstanceProvider] and optionally tearing them down using a - * [PerDisplayInstanceProviderWithTeardown] when displays are disconnected. - * - * It listens to the [DisplayRepository] to detect when displays are added or removed, and - * automatically manages the lifecycle of the per-display instances. - * - * Note that this is a [PerDisplayStoreImpl] 2.0 that doesn't require [CoreStartable] bindings, - * providing all args in the constructor. - */ -class PerDisplayInstanceRepositoryImpl<T> -@AssistedInject -constructor( - @Assisted override val debugName: String, - @Assisted private val instanceProvider: PerDisplayInstanceProvider<T>, - @Background private val backgroundApplicationScope: CoroutineScope, - private val displayRepository: DisplayRepository, - private val initCallback: PerDisplayRepository.InitCallback, -) : PerDisplayRepository<T> { - - private val perDisplayInstances = ConcurrentHashMap<Int, T?>() - - init { - backgroundApplicationScope.launch("$debugName#start") { start() } - } - - private suspend fun start() { - initCallback.onInit(debugName, this) - displayRepository.displayIds.collectLatest { displayIds -> - val toRemove = perDisplayInstances.keys - displayIds - toRemove.forEach { displayId -> - Log.d(TAG, "<$debugName> destroying instance for displayId=$displayId.") - perDisplayInstances.remove(displayId)?.let { instance -> - (instanceProvider as? PerDisplayInstanceProviderWithTeardown)?.destroyInstance( - instance - ) - } - } - } - } - - override fun get(displayId: Int): T? { - if (displayRepository.getDisplay(displayId) == null) { - Log.e(TAG, "<$debugName: Display with id $displayId doesn't exist.") - return null - } - - // If it doesn't exist, create it and put it in the map. - return perDisplayInstances.computeIfAbsent(displayId) { key -> - Log.d(TAG, "<$debugName> creating instance for displayId=$key, as it wasn't available.") - val instance = - traceSection({ "creating instance of $debugName for displayId=$key" }) { - instanceProvider.createInstance(key) - } - if (instance == null) { - Log.e( - TAG, - "<$debugName> returning null because createInstance($key) returned null.", - ) - } - instance - } - } - - @AssistedFactory - interface Factory<T> { - fun create( - debugName: String, - instanceProvider: PerDisplayInstanceProvider<T>, - ): PerDisplayInstanceRepositoryImpl<T> - } - - companion object { - private const val TAG = "PerDisplayInstanceRepo" - } - - override fun toString(): String { - return "PerDisplayInstanceRepositoryImpl(" + - "debugName='$debugName', instances=$perDisplayInstances)" - } -} - -/** - * Provides an instance of a given class **only** for the default display, even if asked for another - * display. - * - * This is useful in case of **flag refactors**: it can be provided instead of an instance of - * [PerDisplayInstanceRepositoryImpl] when a flag related to multi display refactoring is off. - * - * Note that this still requires all instances to be provided by a [PerDisplayInstanceProvider]. If - * you want to provide an existing instance instead for the default display, either implement it in - * a custom [PerDisplayInstanceProvider] (e.g. inject it in the constructor and return it if the - * displayId is zero), or use [SingleInstanceRepositoryImpl]. - */ -class DefaultDisplayOnlyInstanceRepositoryImpl<T>( - override val debugName: String, - private val instanceProvider: PerDisplayInstanceProvider<T>, -) : PerDisplayRepository<T> { - private val lazyDefaultDisplayInstance by lazy { - instanceProvider.createInstance(Display.DEFAULT_DISPLAY) - } - - override fun get(displayId: Int): T? = lazyDefaultDisplayInstance -} - -/** - * Always returns [instance] for any display. - * - * This can be used to provide a single instance based on a flag value during a refactor. Similar to - * [DefaultDisplayOnlyInstanceRepositoryImpl], but also avoids creating the - * [PerDisplayInstanceProvider]. This is useful when you want to provide an existing instance only, - * without even instantiating a [PerDisplayInstanceProvider]. - */ -class SingleInstanceRepositoryImpl<T>(override val debugName: String, private val instance: T) : - PerDisplayRepository<T> { - override fun get(displayId: Int): T? = instance -} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java deleted file mode 100644 index c17094b7456c..000000000000 --- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2023 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.dreams.conditions; - -import com.android.systemui.assist.AssistManager; -import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener; -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.shared.condition.Condition; - -import kotlinx.coroutines.CoroutineScope; - -import javax.inject.Inject; - -/** - * {@link AssistantAttentionCondition} provides a signal when assistant has the user's attention. - */ -public class AssistantAttentionCondition extends Condition { - private final AssistManager mAssistManager; - - private final VisualQueryAttentionListener mVisualQueryAttentionListener = - new VisualQueryAttentionListener() { - @Override - public void onAttentionGained() { - updateCondition(true); - } - - @Override - public void onAttentionLost() { - updateCondition(false); - } - }; - - @Inject - public AssistantAttentionCondition( - @Application CoroutineScope scope, - AssistManager assistManager) { - super(scope); - mAssistManager = assistManager; - } - - @Override - protected void start() { - mAssistManager.addVisualQueryAttentionListener(mVisualQueryAttentionListener); - } - - @Override - protected void stop() { - mAssistManager.removeVisualQueryAttentionListener(mVisualQueryAttentionListener); - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.kt b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.kt new file mode 100644 index 000000000000..838163b1d80a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2025 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.dreams.conditions + +import com.android.systemui.assist.AssistManager +import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.shared.condition.Condition +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope + +/** [AssistantAttentionCondition] provides a signal when assistant has the user's attention. */ +class AssistantAttentionCondition +@Inject +constructor(@Application scope: CoroutineScope, private val assistManager: AssistManager) : + Condition(scope) { + private val visualQueryAttentionListener: VisualQueryAttentionListener = + object : VisualQueryAttentionListener { + override fun onAttentionGained() { + updateCondition(true) + } + + override fun onAttentionLost() { + updateCondition(false) + } + } + + override suspend fun start() { + assistManager.addVisualQueryAttentionListener(visualQueryAttentionListener) + } + + public override fun stop() { + assistManager.removeVisualQueryAttentionListener(visualQueryAttentionListener) + } + + override val startStrategy: Int + get() = START_EAGERLY +} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java deleted file mode 100644 index fb4ed1419688..000000000000 --- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2023 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.dreams.conditions; - -import android.app.DreamManager; - -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.shared.condition.Condition; - -import kotlinx.coroutines.CoroutineScope; - -import javax.inject.Inject; - -/** - * {@link DreamCondition} provides a signal when a dream begins and ends. - */ -public class DreamCondition extends Condition { - private final DreamManager mDreamManager; - private final KeyguardUpdateMonitor mUpdateMonitor; - - private final KeyguardUpdateMonitorCallback mUpdateCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onDreamingStateChanged(boolean dreaming) { - updateCondition(dreaming); - } - }; - - @Inject - public DreamCondition( - @Application CoroutineScope scope, - DreamManager dreamManager, - KeyguardUpdateMonitor monitor) { - super(scope); - mDreamManager = dreamManager; - mUpdateMonitor = monitor; - } - - @Override - protected void start() { - mUpdateMonitor.registerCallback(mUpdateCallback); - updateCondition(mDreamManager.isDreaming()); - } - - @Override - protected void stop() { - mUpdateMonitor.removeCallback(mUpdateCallback); - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.kt b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.kt new file mode 100644 index 000000000000..6968132b7da3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2025 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.dreams.conditions + +import android.app.DreamManager +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.shared.condition.Condition +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope + +/** [DreamCondition] provides a signal when a dream begins and ends. */ +class DreamCondition +@Inject +constructor( + @Application scope: CoroutineScope, + private val _dreamManager: DreamManager, + private val _updateMonitor: KeyguardUpdateMonitor, +) : Condition(scope) { + private val _updateCallback: KeyguardUpdateMonitorCallback = + object : KeyguardUpdateMonitorCallback() { + override fun onDreamingStateChanged(dreaming: Boolean) { + updateCondition(dreaming) + } + } + + override suspend fun start() { + _updateMonitor.registerCallback(_updateCallback) + updateCondition(_dreamManager.isDreaming) + } + + override fun stop() { + _updateMonitor.removeCallback(_updateCallback) + } + + override val startStrategy: Int + get() = START_EAGERLY +} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java index 15f73ee0eda6..a56f07e04d21 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java @@ -42,9 +42,9 @@ import com.android.systemui.dreams.homecontrols.system.HomeControlsRemoteService import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.pipeline.shared.TileSpec; import com.android.systemui.qs.shared.model.TileCategory; -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig; -import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy; -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig; +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig; +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy; +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig; import com.android.systemui.res.R; import com.android.systemui.touch.TouchInsetManager; diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt index 981a55cfda5a..5ebbb463e623 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt @@ -77,9 +77,9 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.zIndex +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.modifiers.thenIf import com.android.systemui.keyboard.shortcut.ui.model.IconSource -import com.android.app.tracing.coroutines.launchTraced as launch /** * A selectable surface with no default focus/hover indications. @@ -235,18 +235,19 @@ fun ShortcutHelperButton( color = color.getDimmedColorIfDisabled(enabled), border = border, modifier = modifier.semantics { role = Role.Button }, - interactionsConfig = InteractionsConfig( - hoverOverlayColor = MaterialTheme.colorScheme.onSurface, - hoverOverlayAlpha = 0.11f, - pressedOverlayColor = MaterialTheme.colorScheme.onSurface, - pressedOverlayAlpha = 0.15f, - focusOutlineColor = MaterialTheme.colorScheme.secondary, - focusOutlineStrokeWidth = 3.dp, - focusOutlinePadding = 2.dp, - surfaceCornerRadius = 28.dp, - focusOutlineCornerRadius = 33.dp, - ), - enabled = enabled + interactionsConfig = + InteractionsConfig( + hoverOverlayColor = MaterialTheme.colorScheme.onSurface, + hoverOverlayAlpha = 0.11f, + pressedOverlayColor = MaterialTheme.colorScheme.onSurface, + pressedOverlayAlpha = 0.15f, + focusOutlineColor = MaterialTheme.colorScheme.secondary, + focusOutlineStrokeWidth = 3.dp, + focusOutlinePadding = 2.dp, + surfaceCornerRadius = 28.dp, + focusOutlineCornerRadius = 33.dp, + ), + enabled = enabled, ) { Row( modifier = @@ -267,7 +268,7 @@ private fun ShortcutHelperButtonContent( iconSource: IconSource, contentColor: Color, text: String?, - contentDescription: String? + contentDescription: String?, ) { if (iconSource.imageVector != null) { Icon( @@ -278,8 +279,7 @@ private fun ShortcutHelperButtonContent( ) } - if (iconSource.imageVector != null && text != null) - Spacer(modifier = Modifier.width(8.dp)) + if (iconSource.imageVector != null && text != null) Spacer(modifier = Modifier.width(8.dp)) if (text != null) { Text( @@ -363,7 +363,7 @@ private class ShortcutHelperInteractionsNode( is HoverInteraction.Exit -> hoverInteractions.remove(interaction.enter) is PressInteraction.Press -> pressInteractions.add(interaction) is PressInteraction.Release -> pressInteractions.remove(interaction.press) - is PressInteraction.Cancel -> pressInteractions.add(interaction.press) + is PressInteraction.Cancel -> pressInteractions.remove(interaction.press) } isHovered.value = hoverInteractions.isNotEmpty() isPressed.value = pressInteractions.isNotEmpty() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index d8fc21af9724..4755e2845587 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -134,7 +134,6 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.keyguard.mediator.ScreenOnCoordinator; import com.android.systemui.CoreStartable; import com.android.systemui.DejankUtils; -import com.android.systemui.Dumpable; import com.android.systemui.EventLogTags; import com.android.systemui.animation.ActivityTransitionAnimator; import com.android.systemui.animation.TransitionAnimator; @@ -194,7 +193,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; @@ -4129,14 +4127,14 @@ public class KeyguardViewMediator implements CoreStartable, private void notifyLockNowCallback() { List<LockNowCallback> callbacks; + synchronized (mLockNowCallbacks) { - callbacks = new ArrayList<LockNowCallback>(mLockNowCallbacks); + callbacks = new ArrayList<>(mLockNowCallbacks); mLockNowCallbacks.clear(); } - Iterator<LockNowCallback> iter = callbacks.listIterator(); - while (iter.hasNext()) { - LockNowCallback callback = iter.next(); - iter.remove(); + + for (int i = 0; i < callbacks.size(); i++) { + final LockNowCallback callback = callbacks.get(i); if (callback.mUserId != mSelectedUserInteractor.getSelectedUserId()) { Log.i(TAG, "Not notifying lockNowCallback due to user mismatch"); continue; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt index 07a31e16384c..6c084038f328 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt @@ -139,18 +139,16 @@ constructor( /** Notifies the callbacks that we've either locked, or decided not to lock. */ private fun notifyShowLockscreenCallbacks() { var callbacks: MutableList<ShowLockscreenCallback> + synchronized(repository.showLockscreenCallbacks) { callbacks = ArrayList(repository.showLockscreenCallbacks) repository.showLockscreenCallbacks.clear() } - val iter: MutableIterator<ShowLockscreenCallback> = callbacks.listIterator() - while (iter.hasNext()) { - val callback = iter.next() - iter.remove() + callbacks.forEach { callback -> if (callback.userId != selectedUserInteractor.getSelectedUserId()) { Log.i(TAG, "Not notifying lockNowCallback due to user mismatch") - continue + return } Log.i(TAG, "Notifying lockNowCallback") try { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt index 0b116ded42da..438dff9cb476 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt @@ -139,7 +139,7 @@ constructor( fun setWallpaperSupportsAmbientMode(supportsAmbientMode: Boolean) { repository.maxAlpha.value = if (supportsAmbientMode) { - 0.7f + 0.54f } else { 1f } diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java index b0c2f8c59deb..b27a4217d454 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java @@ -26,8 +26,7 @@ import java.lang.annotation.Retention; import javax.inject.Qualifier; /** - * A {@link LogBuffer} for QS tiles messages. It's used exclusively in - * {@link com.android.systemui.qs.tiles.base.logging.QSTileLogger} + * A {@link LogBuffer} for QS tiles messages. It's used exclusively in @link QSTileLogger}. */ @Qualifier @Documented diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt index 9e32dd8d74ae..c1658e1f1694 100644 --- a/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt +++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt @@ -122,7 +122,7 @@ constructor( } /** Interface of the ambient light mode callback, which gets triggered when the mode changes. */ - interface Callback { + fun interface Callback { fun onChange(@AmbientLightMode mode: Int) } diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt index 57d709835b2c..ce5fd195d151 100644 --- a/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt +++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt @@ -20,7 +20,7 @@ import android.content.Intent import android.content.IntentFilter import android.os.UserManager import com.android.systemui.broadcast.BroadcastDispatcher -import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.shared.condition.Condition import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -35,7 +35,7 @@ class DirectBootCondition constructor( broadcastDispatcher: BroadcastDispatcher, private val userManager: UserManager, - @Application private val coroutineScope: CoroutineScope, + @Background private val coroutineScope: CoroutineScope, ) : Condition(coroutineScope) { private var job: Job? = null private val directBootFlow = @@ -45,7 +45,7 @@ constructor( .cancellable() .distinctUntilChanged() - override fun start() { + override suspend fun start() { job = coroutineScope.launch { directBootFlow.collect { updateCondition(it) } } updateCondition(!userManager.isUserUnlocked) } diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java deleted file mode 100644 index 5ec81a9a94a1..000000000000 --- a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2024 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.lowlightclock; - -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.shared.condition.Condition; -import com.android.systemui.statusbar.commandline.Command; -import com.android.systemui.statusbar.commandline.CommandRegistry; - -import kotlinx.coroutines.CoroutineScope; - -import java.io.PrintWriter; -import java.util.List; - -import javax.inject.Inject; - -/** - * This condition registers for and fulfills cmd shell commands to force a device into or out of - * low-light conditions. - */ -public class ForceLowLightCondition extends Condition { - /** - * Command root - */ - public static final String COMMAND_ROOT = "low-light"; - /** - * Command for forcing device into low light. - */ - public static final String COMMAND_ENABLE_LOW_LIGHT = "enable"; - - /** - * Command for preventing a device from entering low light. - */ - public static final String COMMAND_DISABLE_LOW_LIGHT = "disable"; - - /** - * Command for clearing previously forced low-light conditions. - */ - public static final String COMMAND_CLEAR_LOW_LIGHT = "clear"; - - private static final String TAG = "ForceLowLightCondition"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - /** - * Default Constructor. - * - * @param commandRegistry command registry to register commands with. - */ - @Inject - public ForceLowLightCondition( - @Application CoroutineScope scope, - CommandRegistry commandRegistry - ) { - super(scope, null, true); - - if (DEBUG) { - Log.d(TAG, "registering commands"); - } - commandRegistry.registerCommand(COMMAND_ROOT, () -> new Command() { - @Override - public void execute(@NonNull PrintWriter pw, @NonNull List<String> args) { - if (args.size() != 1) { - pw.println("no command specified"); - help(pw); - return; - } - - final String cmd = args.get(0); - - if (TextUtils.equals(cmd, COMMAND_ENABLE_LOW_LIGHT)) { - logAndPrint(pw, "forcing low light"); - updateCondition(true); - } else if (TextUtils.equals(cmd, COMMAND_DISABLE_LOW_LIGHT)) { - logAndPrint(pw, "forcing to not enter low light"); - updateCondition(false); - } else if (TextUtils.equals(cmd, COMMAND_CLEAR_LOW_LIGHT)) { - logAndPrint(pw, "clearing any forced low light"); - clearCondition(); - } else { - pw.println("invalid command"); - help(pw); - } - } - - @Override - public void help(@NonNull PrintWriter pw) { - pw.println("Usage: adb shell cmd statusbar low-light <cmd>"); - pw.println("Supported commands:"); - pw.println(" - enable"); - pw.println(" forces device into low-light"); - pw.println(" - disable"); - pw.println(" forces device to not enter low-light"); - pw.println(" - clear"); - pw.println(" clears any previously forced state"); - } - - private void logAndPrint(PrintWriter pw, String message) { - pw.println(message); - if (DEBUG) { - Log.d(TAG, message); - } - } - }); - } - - @Override - protected void start() { - } - - @Override - protected void stop() { - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.kt new file mode 100644 index 000000000000..85a94306d0ea --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.kt @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2025 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.lowlightclock + +import android.text.TextUtils +import android.util.Log +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.shared.condition.Condition +import com.android.systemui.statusbar.commandline.Command +import com.android.systemui.statusbar.commandline.CommandRegistry +import java.io.PrintWriter +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope + +/** + * This condition registers for and fulfills cmd shell commands to force a device into or out of + * low-light conditions. + */ +class ForceLowLightCondition +@Inject +constructor(@Background scope: CoroutineScope, commandRegistry: CommandRegistry) : + Condition(scope, null, true) { + /** + * Default Constructor. + * + * @param commandRegistry command registry to register commands with. + */ + init { + if (DEBUG) { + Log.d(TAG, "registering commands") + } + commandRegistry.registerCommand(COMMAND_ROOT) { + object : Command { + override fun execute(pw: PrintWriter, args: List<String>) { + if (args.size != 1) { + pw.println("no command specified") + help(pw) + return + } + + val cmd = args[0] + + if (TextUtils.equals(cmd, COMMAND_ENABLE_LOW_LIGHT)) { + logAndPrint(pw, "forcing low light") + updateCondition(true) + } else if (TextUtils.equals(cmd, COMMAND_DISABLE_LOW_LIGHT)) { + logAndPrint(pw, "forcing to not enter low light") + updateCondition(false) + } else if (TextUtils.equals(cmd, COMMAND_CLEAR_LOW_LIGHT)) { + logAndPrint(pw, "clearing any forced low light") + clearCondition() + } else { + pw.println("invalid command") + help(pw) + } + } + + override fun help(pw: PrintWriter) { + pw.println("Usage: adb shell cmd statusbar low-light <cmd>") + pw.println("Supported commands:") + pw.println(" - enable") + pw.println(" forces device into low-light") + pw.println(" - disable") + pw.println(" forces device to not enter low-light") + pw.println(" - clear") + pw.println(" clears any previously forced state") + } + + private fun logAndPrint(pw: PrintWriter, message: String) { + pw.println(message) + if (DEBUG) { + Log.d(TAG, message) + } + } + } + } + } + + override suspend fun start() {} + + override fun stop() {} + + override val startStrategy: Int + get() = START_EAGERLY + + companion object { + /** Command root */ + const val COMMAND_ROOT: String = "low-light" + + /** Command for forcing device into low light. */ + const val COMMAND_ENABLE_LOW_LIGHT: String = "enable" + + /** Command for preventing a device from entering low light. */ + const val COMMAND_DISABLE_LOW_LIGHT: String = "disable" + + /** Command for clearing previously forced low-light conditions. */ + const val COMMAND_CLEAR_LOW_LIGHT: String = "clear" + + private const val TAG = "ForceLowLightCondition" + private val DEBUG = Log.isLoggable(TAG, Log.DEBUG) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java deleted file mode 100644 index c1a24e7e020e..000000000000 --- a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2024 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.lowlightclock; - -import com.android.internal.logging.UiEventLogger; -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.shared.condition.Condition; - -import kotlinx.coroutines.CoroutineScope; - -import javax.inject.Inject; - -/** - * Condition for monitoring when the device enters and exits lowlight mode. - */ -public class LowLightCondition extends Condition { - private final AmbientLightModeMonitor mAmbientLightModeMonitor; - private final UiEventLogger mUiEventLogger; - - @Inject - public LowLightCondition(@Application CoroutineScope scope, - AmbientLightModeMonitor ambientLightModeMonitor, - UiEventLogger uiEventLogger) { - super(scope); - mAmbientLightModeMonitor = ambientLightModeMonitor; - mUiEventLogger = uiEventLogger; - } - - @Override - protected void start() { - mAmbientLightModeMonitor.start(this::onLowLightChanged); - } - - @Override - protected void stop() { - mAmbientLightModeMonitor.stop(); - - // Reset condition met to false. - updateCondition(false); - } - - @Override - public int getStartStrategy() { - // As this condition keeps the lowlight sensor active, it should only run when needed. - return START_WHEN_NEEDED; - } - - private void onLowLightChanged(int lowLightMode) { - if (lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED) { - // Ignore undecided mode changes. - return; - } - - final boolean isLowLight = lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK; - if (isLowLight == isConditionMet()) { - // No change in condition, don't do anything. - return; - } - mUiEventLogger.log(isLowLight ? LowLightDockEvent.AMBIENT_LIGHT_TO_DARK - : LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT); - updateCondition(isLowLight); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.kt new file mode 100644 index 000000000000..34e9a6351180 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2025 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.lowlightclock + +import com.android.internal.logging.UiEventLogger +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.shared.condition.Condition +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope + +/** Condition for monitoring when the device enters and exits lowlight mode. */ +class LowLightCondition +@Inject +constructor( + @Background scope: CoroutineScope, + private val ambientLightModeMonitor: AmbientLightModeMonitor, + private val uiEventLogger: UiEventLogger, +) : Condition(scope) { + override suspend fun start() { + ambientLightModeMonitor.start { lowLightMode: Int -> onLowLightChanged(lowLightMode) } + } + + override fun stop() { + ambientLightModeMonitor.stop() + + // Reset condition met to false. + updateCondition(false) + } + + override val startStrategy: Int + get() = // As this condition keeps the lowlight sensor active, it should only run when + // needed. + START_WHEN_NEEDED + + private fun onLowLightChanged(lowLightMode: Int) { + if (lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED) { + // Ignore undecided mode changes. + return + } + + val isLowLight = lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK + if (isLowLight == isConditionMet) { + // No change in condition, don't do anything. + return + } + uiEventLogger.log( + if (isLowLight) LowLightDockEvent.AMBIENT_LIGHT_TO_DARK + else LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT + ) + updateCondition(isLowLight) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java deleted file mode 100644 index 81572554cb86..000000000000 --- a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2024 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.lowlightclock; - -import android.content.res.Resources; -import android.database.ContentObserver; -import android.os.UserHandle; -import android.provider.Settings; -import android.util.Log; - -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.shared.condition.Condition; -import com.android.systemui.util.settings.SecureSettings; - -import kotlinx.coroutines.CoroutineScope; - -import javax.inject.Inject; - -/** - * Condition for monitoring if the screensaver setting is enabled. - */ -public class ScreenSaverEnabledCondition extends Condition { - private static final String TAG = ScreenSaverEnabledCondition.class.getSimpleName(); - - private final boolean mScreenSaverEnabledByDefaultConfig; - private final SecureSettings mSecureSettings; - - private final ContentObserver mScreenSaverSettingObserver = new ContentObserver(null) { - @Override - public void onChange(boolean selfChange) { - updateScreenSaverEnabledSetting(); - } - }; - - @Inject - public ScreenSaverEnabledCondition(@Application CoroutineScope scope, @Main Resources resources, - SecureSettings secureSettings) { - super(scope); - mScreenSaverEnabledByDefaultConfig = resources.getBoolean( - com.android.internal.R.bool.config_dreamsEnabledByDefault); - mSecureSettings = secureSettings; - } - - @Override - protected void start() { - mSecureSettings.registerContentObserverForUserSync( - Settings.Secure.SCREENSAVER_ENABLED, - mScreenSaverSettingObserver, UserHandle.USER_CURRENT); - updateScreenSaverEnabledSetting(); - } - - @Override - protected void stop() { - mSecureSettings.unregisterContentObserverSync(mScreenSaverSettingObserver); - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } - - private void updateScreenSaverEnabledSetting() { - final boolean enabled = mSecureSettings.getIntForUser( - Settings.Secure.SCREENSAVER_ENABLED, - mScreenSaverEnabledByDefaultConfig ? 1 : 0, - UserHandle.USER_CURRENT) != 0; - if (!enabled) { - Log.i(TAG, "Disabling low-light clock because screen saver has been disabled"); - } - updateCondition(enabled); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.kt new file mode 100644 index 000000000000..e761cc0692f7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2025 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.lowlightclock + +import android.content.res.Resources +import android.database.ContentObserver +import android.os.UserHandle +import android.provider.Settings +import android.util.Log +import com.android.internal.R +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.shared.condition.Condition +import com.android.systemui.util.settings.SecureSettings +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope + +/** Condition for monitoring if the screensaver setting is enabled. */ +class ScreenSaverEnabledCondition +@Inject +constructor( + @Background scope: CoroutineScope, + @Main resources: Resources, + private val secureSettings: SecureSettings, +) : Condition(scope) { + private val screenSaverEnabledByDefaultConfig = + resources.getBoolean(R.bool.config_dreamsEnabledByDefault) + + private val screenSaverSettingObserver: ContentObserver = + object : ContentObserver(null) { + override fun onChange(selfChange: Boolean) { + updateScreenSaverEnabledSetting() + } + } + + public override suspend fun start() { + secureSettings.registerContentObserverForUserSync( + Settings.Secure.SCREENSAVER_ENABLED, + screenSaverSettingObserver, + UserHandle.USER_CURRENT, + ) + updateScreenSaverEnabledSetting() + } + + override fun stop() { + secureSettings.unregisterContentObserverSync(screenSaverSettingObserver) + } + + override val startStrategy: Int + get() = START_EAGERLY + + private fun updateScreenSaverEnabledSetting() { + val enabled = + secureSettings.getIntForUser( + Settings.Secure.SCREENSAVER_ENABLED, + if (screenSaverEnabledByDefaultConfig) 1 else 0, + UserHandle.USER_CURRENT, + ) != 0 + if (!enabled) { + Log.i(TAG, "Disabling low-light clock because screen saver has been disabled") + } + updateCondition(enabled) + } + + companion object { + private val TAG: String = ScreenSaverEnabledCondition::class.java.simpleName + } +} diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt index 71cb74543485..68cd80798c4b 100644 --- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt +++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt @@ -17,9 +17,9 @@ package com.android.systemui.model import android.util.Log import android.view.Display +import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown import com.android.systemui.Dumpable import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.display.data.repository.PerDisplayInstanceProviderWithTeardown import com.android.systemui.dump.DumpManager import com.android.systemui.model.SysUiState.SysUiStateCallback import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 49fa3ba2da61..88f679e73388 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -72,4 +72,8 @@ public interface NavigationBarController { /** @return {@link NavigationBar} on the default display. */ @Nullable NavigationBar getDefaultNavigationBar(); + + /** @return {@link NavigationBar} for a specific display, or null if not available. */ + @Nullable + NavigationBar getNavigationBar(int displayId); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt index 45ff7f4f87ef..f096510fa5dc 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt @@ -54,4 +54,6 @@ class NavigationBarControllerEmptyImpl @Inject constructor() : NavigationBarCont override fun isOverviewEnabled(displayId: Int) = false override fun getDefaultNavigationBar(): NavigationBar? = null + + override fun getNavigationBar(displayId: Int): NavigationBar? = null } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java index 50d0a459da66..8fbf8b60af9a 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java @@ -469,7 +469,8 @@ public class NavigationBarControllerImpl implements return (navBar == null) ? null : navBar.getView(); } - private @Nullable NavigationBar getNavigationBar(int displayId) { + @Override + public @Nullable NavigationBar getNavigationBar(int displayId) { return mNavigationBars.get(displayId); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java index 914e0f74e4a0..39482bea0111 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java @@ -24,13 +24,16 @@ import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; +import com.android.app.displaylib.PerDisplayRepository; import com.android.app.viewcapture.ViewCapture; import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.dagger.qualifiers.DisplayId; +import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope; import com.android.systemui.navigationbar.views.NavigationBarFrame; import com.android.systemui.navigationbar.views.NavigationBarView; import com.android.systemui.res.R; +import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround; import dagger.Lazy; import dagger.Module; @@ -71,6 +74,20 @@ public interface NavigationBarModule { return context.getSystemService(WindowManager.class); } + /** A SysUiState for the navigation bar display. */ + @Provides + @NavigationBarScope + @DisplayId + static SysUiState provideSysUiState(@DisplayId Context context, + SysUiState defaultState, + PerDisplayRepository<SysUiState> repository) { + if (ShadeWindowGoesAround.isEnabled()) { + return repository.get(context.getDisplayId()); + } else { + return defaultState; + } + } + /** A ViewCaptureAwareWindowManager specific to the display's context. */ @Provides @NavigationBarScope diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java index f95f45906b23..8b5b3adeef1f 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java @@ -569,7 +569,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements NavigationModeController navigationModeController, StatusBarStateController statusBarStateController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, - SysUiState sysUiFlagsContainer, + @DisplayId SysUiState sysUiFlagsContainer, UserTracker userTracker, CommandQueue commandQueue, Optional<Pip> pipOptional, @@ -1694,7 +1694,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements (mNavbarFlags & NAVBAR_BACK_DISMISS_IME) != 0) .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY, allowSystemGestureIgnoringBarVisibility()) - .commitUpdate(mDisplayId); + .commitUpdate(); } private void updateAssistantEntrypoints(boolean assistantAvailable, diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java index 36cb8fa374b0..cbc4c26b2f94 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java @@ -740,15 +740,13 @@ public class NavigationBarView extends FrameLayout { /** */ public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) { - int displayId = mContext.getDisplayId(); - sysUiState.setFlag(SYSUI_STATE_OVERVIEW_DISABLED, (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0) .setFlag(SYSUI_STATE_HOME_DISABLED, (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0) .setFlag(SYSUI_STATE_SEARCH_DISABLED, (mDisabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0) - .commitUpdate(displayId); + .commitUpdate(); } public void setInScreenPinning(boolean active) { diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt index 5d5465633f9f..fb3271e57b08 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt @@ -32,16 +32,16 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.tiles.NotesTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.impl.notes.domain.NotesTileMapper +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileDataInteractor import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileUserActionInteractor import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.impl.notes.ui.mapper.NotesTileMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java deleted file mode 100644 index ea2bf6a44884..000000000000 --- a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2023 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.process.condition; - -import com.android.systemui.dagger.qualifiers.Application; -import com.android.systemui.process.ProcessWrapper; -import com.android.systemui.shared.condition.Condition; - -import kotlinx.coroutines.CoroutineScope; - -import javax.inject.Inject; - -/** - * {@link SystemProcessCondition} checks to make sure the current process is being ran by the - * System User. - */ -public class SystemProcessCondition extends Condition { - private final ProcessWrapper mProcessWrapper; - - @Inject - public SystemProcessCondition(@Application CoroutineScope scope, - ProcessWrapper processWrapper) { - super(scope); - mProcessWrapper = processWrapper; - } - - @Override - protected void start() { - updateCondition(mProcessWrapper.isSystemUser()); - } - - @Override - protected void stop() { - } - - @Override - public int getStartStrategy() { - return START_EAGERLY; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.kt b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.kt new file mode 100644 index 000000000000..9a424c3aab41 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2025 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.process.condition + +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.process.ProcessWrapper +import com.android.systemui.shared.condition.Condition +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope + +/** + * [SystemProcessCondition] checks to make sure the current process is being ran by the System User. + */ +class SystemProcessCondition +@Inject +constructor(@Application scope: CoroutineScope, private val processWrapper: ProcessWrapper) : + Condition(scope) { + override val startStrategy: Int + get() = START_EAGERLY + + override suspend fun start() { + updateCondition(processWrapper.isSystemUser) + } + + override fun stop() {} +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt index e2a39160defc..f1193fa11dce 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt @@ -24,7 +24,7 @@ import com.android.systemui.qs.external.QSExternalModule import com.android.systemui.qs.panels.dagger.PanelsModule import com.android.systemui.qs.pipeline.dagger.QSPipelineModule import com.android.systemui.qs.tileimpl.QSTileImpl -import com.android.systemui.qs.tiles.di.QSTilesModule +import com.android.systemui.qs.tiles.base.ui.model.QSTilesModule import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl import dagger.Binds diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt index a2cee3b68d49..ec0a754d8f1f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt @@ -25,7 +25,7 @@ import com.android.systemui.qs.panels.data.repository.StockTilesRepository import com.android.systemui.qs.panels.domain.model.EditTilesModel import com.android.systemui.qs.panels.shared.model.EditTileData import com.android.systemui.qs.shared.model.TileCategory -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider import javax.inject.Inject @SysUISingleton @@ -50,7 +50,7 @@ constructor( it, Icon.Resource( config.uiConfig.iconRes, - ContentDescription.Resource(config.uiConfig.labelRes) + ContentDescription.Resource(config.uiConfig.labelRes), ), Text.Resource(config.uiConfig.labelRes), null, @@ -61,7 +61,7 @@ constructor( it, Icon.Resource( android.R.drawable.star_on, - ContentDescription.Loaded(it.spec) + ContentDescription.Loaded(it.spec), ), Text.Loaded(it.spec), null, diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt index 00cd96ce37cb..46a6e4a90c57 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt @@ -19,14 +19,14 @@ package com.android.systemui.qs.panels.domain.interactor import android.os.UserHandle import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated +import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map -import javax.inject.Inject /** * Uses the [QSTileAvailabilityInteractor] from the new tiles to provide a map of availability, for @@ -38,23 +38,26 @@ import javax.inject.Inject class NewTilesAvailabilityInteractor @Inject constructor( - private val availabilityInteractors: - Map<String, @JvmSuppressWildcards QSTileAvailabilityInteractor>, - userRepository: UserRepository, + private val availabilityInteractors: + Map<String, @JvmSuppressWildcards QSTileAvailabilityInteractor>, + userRepository: UserRepository, ) { val newTilesAvailable: Flow<Map<TileSpec, Boolean>> = - userRepository.selectedUserInfo.map { it.id } - .flatMapLatestConflated { userId -> - if (availabilityInteractors.isEmpty()) { - flowOf(emptyMap()) - } else { - combine(availabilityInteractors.map { (spec, interactor) -> - interactor.availability(UserHandle.of(userId)).map { - TileSpec.create(spec) to it - } - }) { - it.toMap() + userRepository.selectedUserInfo + .map { it.id } + .flatMapLatestConflated { userId -> + if (availabilityInteractors.isEmpty()) { + flowOf(emptyMap()) + } else { + combine( + availabilityInteractors.map { (spec, interactor) -> + interactor.availability(UserHandle.of(userId)).map { + TileSpec.create(spec) to it } } + ) { + it.toMap() } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt index d20b360756d7..728652e6e5c4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt @@ -82,6 +82,7 @@ fun ContentScope.QuickQuickSettings( viewModel.tileHapticsViewModelFactoryProvider, // There should be no QuickQuickSettings when the details view is enabled. detailsViewModel = null, + isVisible = listening, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt index 50012abc69d6..b3b6cfdcc306 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt @@ -45,6 +45,7 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.key +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -102,6 +103,7 @@ fun LargeTileContent( sideDrawable: Drawable?, colors: TileColors, squishiness: () -> Float, + isVisible: () -> Boolean = { true }, accessibilityUiState: AccessibilityUiState? = null, iconShape: RoundedCornerShape = RoundedCornerShape(CommonTileDefaults.InactiveCornerRadius), toggleClick: (() -> Unit)? = null, @@ -158,6 +160,7 @@ fun LargeTileContent( secondaryLabel = secondaryLabel, colors = colors, accessibilityUiState = accessibilityUiState, + isVisible = isVisible, ) if (sideDrawable != null) { @@ -176,6 +179,7 @@ fun LargeTileLabels( secondaryLabel: String?, colors: TileColors, modifier: Modifier = Modifier, + isVisible: () -> Boolean = { true }, accessibilityUiState: AccessibilityUiState? = null, ) { val animatedLabelColor by animateColorAsState(colors.label, label = "QSTileLabelColor") @@ -186,12 +190,14 @@ fun LargeTileLabels( text = label, style = MaterialTheme.typography.labelLarge, color = { animatedLabelColor }, + isVisible = isVisible, ) if (!TextUtils.isEmpty(secondaryLabel)) { TileLabel( secondaryLabel ?: "", color = { animatedSecondaryLabelColor }, style = MaterialTheme.typography.bodyMedium, + isVisible = isVisible, modifier = Modifier.thenIf( accessibilityUiState?.stateDescription?.contains(secondaryLabel ?: "") == @@ -277,36 +283,50 @@ private fun TileLabel( color: ColorProducer, style: TextStyle, modifier: Modifier = Modifier, + isVisible: () -> Boolean = { true }, ) { + var textSize by remember { mutableIntStateOf(0) } + BasicText( text = text, color = color, style = style, maxLines = 1, + onTextLayout = { textSize = it.size.width }, modifier = modifier .fillMaxWidth() - .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen } + .graphicsLayer { + if (textSize > size.width) { + compositingStrategy = CompositingStrategy.Offscreen + } + } .drawWithContent { drawContent() - // Draw a blur over the end of the text - val edgeWidthPx = TileLabelBlurWidth.toPx() - drawRect( - topLeft = Offset(size.width - edgeWidthPx, 0f), - size = Size(edgeWidthPx, size.height), - brush = - Brush.horizontalGradient( - colors = listOf(Color.Transparent, Color.Black), - startX = size.width, - endX = size.width - edgeWidthPx, - ), - blendMode = BlendMode.DstIn, - ) + if (textSize > size.width) { + // Draw a blur over the end of the text + val edgeWidthPx = TileLabelBlurWidth.toPx() + drawRect( + topLeft = Offset(size.width - edgeWidthPx, 0f), + size = Size(edgeWidthPx, size.height), + brush = + Brush.horizontalGradient( + colors = listOf(Color.Transparent, Color.Black), + startX = size.width, + endX = size.width - edgeWidthPx, + ), + blendMode = BlendMode.DstIn, + ) + } } - .basicMarquee( - iterations = TILE_MARQUEE_ITERATIONS, - initialDelayMillis = TILE_INITIAL_DELAY_MILLIS, - ), + .thenIf(isVisible()) { + // Only apply the marquee when the label is visible, which is needed for the + // always composed QS + Modifier.basicMarquee( + iterations = TILE_MARQUEE_ITERATIONS, + initialDelayMillis = TILE_INITIAL_DELAY_MILLIS, + ) + }, ) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt index 6236ada46374..984343a45797 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt @@ -78,8 +78,15 @@ constructor( } val columns = columnsWithMediaViewModel.columns + val largeTiles by iconTilesViewModel.largeTilesState val largeTilesSpan by iconTilesViewModel.largeTilesSpanState - val sizedTiles = tiles.map { SizedTileImpl(it, it.spec.width(largeTilesSpan)) } + // Tiles or largeTiles may be updated while this is composed, so listen to any changes + val sizedTiles = + remember(tiles, largeTiles, largeTilesSpan) { + tiles.map { + SizedTileImpl(it, if (largeTiles.contains(it.spec)) largeTilesSpan else 1) + } + } val bounceables = remember(sizedTiles) { List(sizedTiles.size) { BounceableTileViewModel() } } val squishiness by viewModel.squishinessViewModel.squishiness.collectAsStateWithLifecycle() @@ -112,6 +119,7 @@ constructor( isLastInRow = isLastInColumn, ), detailsViewModel = detailsViewModel, + isVisible = listening, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt index 6bafd432669a..e24718285312 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt @@ -139,6 +139,7 @@ fun Tile( bounceableInfo: BounceableInfo, tileHapticsViewModelFactoryProvider: TileHapticsViewModelFactoryProvider, modifier: Modifier = Modifier, + isVisible: () -> Boolean = { true }, detailsViewModel: DetailsViewModel?, ) { trace(tile.traceName) { @@ -249,6 +250,7 @@ fun Tile( onLongClick = longClick, accessibilityUiState = uiState.accessibilityUiState, squishiness = squishiness, + isVisible = isVisible, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt index a9d673aa7400..d6705a68d32c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt @@ -35,6 +35,9 @@ constructor( private val hydrator = Hydrator("DynamicIconTilesViewModel") private val interactor = interactorFactory.create() + val largeTilesState = + hydrator.hydratedStateOf(traceName = "largeTiles", source = iconTilesViewModel.largeTiles) + val largeTilesSpanState = hydrator.hydratedStateOf( traceName = "largeTilesSpan", diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt index 16aa99e22ae2..f155629e093f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt @@ -35,8 +35,8 @@ import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractorImpl import com.android.systemui.qs.pipeline.domain.startable.QSPipelineCoreStartable import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger -import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractorImpl +import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractorImpl import dagger.Binds import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt index c70a854a2ca0..a3846e3a5903 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt @@ -42,7 +42,7 @@ import com.android.systemui.qs.pipeline.domain.model.TileModel import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger -import com.android.systemui.qs.tiles.di.NewQSTileFactory +import com.android.systemui.qs.tiles.base.ui.model.NewQSTileFactory import com.android.systemui.qs.toProto import com.android.systemui.retail.data.repository.RetailModeRepository import com.android.systemui.settings.UserTracker diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt index 52b02066c35a..43e3de2040d7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt @@ -39,12 +39,12 @@ import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.asQSTileIcon import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileState import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import javax.inject.Inject import kotlinx.coroutines.runBlocking @@ -121,6 +121,7 @@ constructor( label = tileLabel secondaryLabel = tileState.secondaryLabel contentDescription = tileState.contentDescription + stateDescription = tileState.stateDescription expandedAccessibilityClassName = tileState.expandedAccessibilityClassName } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt index ad5dd27f07c2..fcfa46f07ab4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt @@ -42,13 +42,13 @@ import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.asQSTileIcon import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileState import com.android.systemui.qs.tiles.dialog.ModesDetailsViewModel import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel -import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ui.dialog.viewmodel.ModesDialogViewModel import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt index 5ba1527dbf69..c021b2270b7b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt @@ -33,12 +33,12 @@ import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl -import com.android.systemui.qs.tiles.impl.notes.domain.NotesTileMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileState import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileDataInteractor import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileUserActionInteractor import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.impl.notes.ui.mapper.NotesTileMapper import com.android.systemui.res.R import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandler.kt index 972b20e138d9..386e1a448611 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.actions +package com.android.systemui.qs.tiles.base.domain.actions import android.app.PendingIntent import android.content.Intent @@ -36,14 +36,14 @@ interface QSTileIntentUserInputHandler { fun handle( expandable: Expandable?, intent: Intent, - dismissShadeShowOverLockScreenWhenLocked: Boolean = false + dismissShadeShowOverLockScreenWhenLocked: Boolean = false, ) /** @param requestLaunchingDefaultActivity used in case !pendingIndent.isActivity */ fun handle( expandable: Expandable?, pendingIntent: PendingIntent, - requestLaunchingDefaultActivity: Boolean = false + requestLaunchingDefaultActivity: Boolean = false, ) } @@ -59,7 +59,7 @@ constructor( override fun handle( expandable: Expandable?, intent: Intent, - dismissShadeShowOverLockScreenWhenLocked: Boolean + dismissShadeShowOverLockScreenWhenLocked: Boolean, ) { val animationController: ActivityTransitionAnimator.Controller? = expandable?.activityTransitionController( @@ -70,7 +70,7 @@ constructor( intent, true /* dismissShade */, animationController, - true /* showOverLockscreenWhenLocked */ + true, /* showOverLockscreenWhenLocked */ ) } else { activityStarter.postStartActivityDismissingKeyguard(intent, 0, animationController) @@ -81,7 +81,7 @@ constructor( override fun handle( expandable: Expandable?, pendingIntent: PendingIntent, - requestLaunchingDefaultActivity: Boolean + requestLaunchingDefaultActivity: Boolean, ) { if (pendingIntent.isActivity) { val animationController: ActivityTransitionAnimator.Controller? = @@ -101,7 +101,7 @@ constructor( packageManager.queryIntentActivitiesAsUser( intent, PackageManager.ResolveInfoFlags.of(0L), - userHandle.identifier + userHandle.identifier, ) intents .firstOrNull { it.activityInfo.exported } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractor.kt index 45775272e01f..da4d3d408c84 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractor.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import android.content.Context import android.os.UserHandle @@ -26,7 +26,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor.PolicyResult +import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor.PolicyResult import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -110,17 +110,9 @@ class RestrictedLockProxy @Inject constructor(@ShadeDisplayAware private val con @WorkerThread fun hasBaseUserRestriction(userId: Int, userRestriction: String?): Boolean = - RestrictedLockUtilsInternal.hasBaseUserRestriction( - context, - userRestriction, - userId, - ) + RestrictedLockUtilsInternal.hasBaseUserRestriction(context, userRestriction, userId) @WorkerThread fun getEnforcedAdmin(userId: Int, userRestriction: String?): EnforcedAdmin? = - RestrictedLockUtilsInternal.checkIfRestrictionEnforced( - context, - userRestriction, - userId, - ) + RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context, userRestriction, userId) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileDataInteractor.kt index 9a776f2832d4..1eb5315a5512 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileDataInteractor.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import android.os.UserHandle +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf @@ -49,10 +50,11 @@ interface QSTileAvailabilityInteractor { fun availability(user: UserHandle): Flow<Boolean> companion object { - val AlwaysAvailableInteractor = object : QSTileAvailabilityInteractor { - override fun availability(user: UserHandle): Flow<Boolean> { - return flowOf(true) + val AlwaysAvailableInteractor = + object : QSTileAvailabilityInteractor { + override fun availability(user: UserHandle): Flow<Boolean> { + return flowOf(true) + } } - } } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileUserActionInteractor.kt index 8ad4e16291c2..e49616c8326f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileUserActionInteractor.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import android.annotation.WorkerThread -import com.android.systemui.plugins.qs.TileDetailsViewModel +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput interface QSTileUserActionInteractor<DATA_TYPE> { /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/DataUpdateTrigger.kt index 4f25d3cde6c3..a77e551a4a33 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/DataUpdateTrigger.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.model /** Event that triggers data update */ sealed interface DataUpdateTrigger { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInput.kt index 77ff6092063f..59236be8ebab 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInput.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,14 +14,10 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.model import android.os.UserHandle -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction /** @see QSTileUserActionInteractor.handleInput */ -data class QSTileInput<T>( - val user: UserHandle, - val action: QSTileUserAction, - val data: T, -) +data class QSTileInput<T>(val user: UserHandle, val action: QSTileUserAction, val data: T) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLogger.kt index 8ec8a6d1e730..04d40eeb3800 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLogger.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.logging +package com.android.systemui.qs.tiles.base.shared.logging import androidx.annotation.GuardedBy import com.android.systemui.dagger.SysUISingleton @@ -24,8 +24,8 @@ import com.android.systemui.log.core.LogLevel import com.android.systemui.log.dagger.QSTilesLogBuffers import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.statusbar.StatusBarState import javax.inject.Inject @@ -65,22 +65,19 @@ constructor( "statusBarState=${StatusBarState.toString(int1)}, " + "hasState=$bool1, " + "hasData=$bool2" - } + }, ) } /** Tracks user action when it's rejected by false gestures */ - fun logUserActionRejectedByFalsing( - userAction: QSTileUserAction, - tileSpec: TileSpec, - ) { + fun logUserActionRejectedByFalsing(userAction: QSTileUserAction, tileSpec: TileSpec) { tileSpec .getLogBuffer() .log( tileSpec.getLogTag(), LogLevel.DEBUG, { str1 = userAction.toLogString() }, - { "tile $str1: rejected by falsing" } + { "tile $str1: rejected by falsing" }, ) } @@ -96,7 +93,7 @@ constructor( tileSpec.getLogTag(), LogLevel.DEBUG, { str1 = userAction.toLogString() }, - { "tile $str1: rejected by policy, restriction: $restriction" } + { "tile $str1: rejected by policy, restriction: $restriction" }, ) } @@ -124,7 +121,7 @@ constructor( "statusBarState=${StatusBarState.toString(int1)}, " + "state=$str2, " + "data=$str3" - } + }, ) } @@ -141,11 +138,7 @@ constructor( } /** Tracks state changes based on the data and trigger event. */ - fun <T> logStateUpdate( - tileSpec: TileSpec, - tileState: QSTileState, - data: T, - ) { + fun <T> logStateUpdate(tileSpec: TileSpec, tileState: QSTileState, data: T) { tileSpec .getLogBuffer() .log( @@ -155,41 +148,23 @@ constructor( str1 = tileState.toLogString() str2 = data.toString().take(DATA_MAX_LENGTH) }, - { "tile state update: state=$str1, data=$str2" } + { "tile state update: state=$str1, data=$str2" }, ) } - fun logError( - tileSpec: TileSpec, - message: String, - error: Throwable, - ) { - tileSpec - .getLogBuffer() - .log( - tileSpec.getLogTag(), - LogLevel.ERROR, - {}, - { message }, - error, - ) + fun logError(tileSpec: TileSpec, message: String, error: Throwable) { + tileSpec.getLogBuffer().log(tileSpec.getLogTag(), LogLevel.ERROR, {}, { message }, error) } /** Log with level [LogLevel.WARNING] */ - fun logWarning( - tileSpec: TileSpec, - message: String, - ) { + fun logWarning(tileSpec: TileSpec, message: String) { tileSpec .getLogBuffer() .log(tileSpec.getLogTag(), LogLevel.WARNING, { str1 = message }, { str1!! }) } /** Log with level [LogLevel.INFO] */ - fun logInfo( - tileSpec: TileSpec, - message: String, - ) { + fun logInfo(tileSpec: TileSpec, message: String) { tileSpec .getLogBuffer() .log(tileSpec.getLogTag(), LogLevel.INFO, { str1 = message }, { str1!! }) @@ -214,7 +189,7 @@ constructor( factory.create( this.getLogTag(), BUFFER_MAX_SIZE /* maxSize */, - false /* systrace */ + false, /* systrace */ ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfig.kt index 3a9cb170040c..7c2a08f6c4a2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfig.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import android.content.res.Resources import androidx.annotation.DrawableRes diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProvider.kt index 4dbddd91092a..e2d1605ca1fa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import com.android.internal.util.Preconditions import com.android.systemui.dagger.SysUISingleton @@ -51,7 +51,7 @@ constructor( val keyTileSpec = entry.key Preconditions.checkArgument( configTileSpec == keyTileSpec, - "A wrong config is injected keySpec=$keyTileSpec configSpec=$configTileSpec" + "A wrong config is injected keySpec=$keyTileSpec configSpec=$configTileSpec", ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileCoroutineScopeFactory.kt index 5f476ea7e274..018a06f94190 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileCoroutineScopeFactory.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import com.android.systemui.coroutines.newTracingContext import com.android.systemui.dagger.qualifiers.Background diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileScope.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileScope.kt index a412de364c19..a0caedb21d29 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileScope.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileScope.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.di +package com.android.systemui.qs.tiles.base.shared.model import javax.inject.Scope diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileState.kt index c6af729cd4a7..5a19eae73d5e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileState.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import android.content.res.Resources import android.content.res.Resources.Theme diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileUserAction.kt index bf3bc73cf72e..bbf04f63fa49 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileUserAction.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalytics.kt index 1d427775dad6..86991485de9d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalytics.kt @@ -14,22 +14,18 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.analytics +package com.android.systemui.qs.tiles.base.ui.analytics import com.android.internal.logging.UiEventLogger import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.QSEvent -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import javax.inject.Inject /** Tracks QS tiles analytic events to [UiEventLogger]. */ @SysUISingleton -class QSTileAnalytics -@Inject -constructor( - private val uiEventLogger: UiEventLogger, -) { +class QSTileAnalytics @Inject constructor(private val uiEventLogger: UiEventLogger) { fun trackUserAction(config: QSTileConfig, action: QSTileUserAction) { logAction(config, action) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactory.kt index f65fdb540527..fca7abef5d32 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.di +package com.android.systemui.qs.tiles.base.ui.model import com.android.systemui.dagger.SysUISingleton import com.android.systemui.plugins.qs.QSFactory import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModelAdapter -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelAdapter +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel import javax.inject.Inject import javax.inject.Provider @@ -58,8 +58,7 @@ constructor( is TileSpec.PlatformTileSpec -> tileMap[tileSpec]?.get()?.takeIf { it !is StubQSTileViewModel } is TileSpec.Invalid -> null - } - ?: return null + } ?: return null return adapterFactory.create(viewModel) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileComponent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileComponent.kt index 5f692f2f5a73..f63c2db70131 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileComponent.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,12 +14,11 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.di +package com.android.systemui.qs.tiles.base.ui.model -import com.android.systemui.plugins.qs.TileDetailsViewModel -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope import kotlinx.coroutines.CoroutineScope /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataToStateMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileDataToStateMapper.kt index 2bc664311644..7be2ed114130 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataToStateMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileDataToStateMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.ui.model import androidx.annotation.WorkerThread -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState interface QSTileDataToStateMapper<DATA_TYPE> { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTilesModule.kt index 222fa3efbe94..6b31539f1a03 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTilesModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.di +package com.android.systemui.qs.tiles.base.ui.model import android.content.Context import android.content.res.Resources.Theme import com.android.systemui.qs.external.CustomTileStatePersister import com.android.systemui.qs.external.CustomTileStatePersisterImpl -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerImpl -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProviderImpl -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerImpl +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProviderImpl +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.impl.custom.ui.model.CustomTileComponent import com.android.systemui.shade.ShadeDisplayAware import dagger.Binds import dagger.Module @@ -35,12 +35,7 @@ import dagger.Provides import dagger.multibindings.Multibinds /** Module listing subcomponents */ -@Module( - subcomponents = - [ - CustomTileComponent::class, - ] -) +@Module(subcomponents = [CustomTileComponent::class]) interface QSTilesModule { /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModel.kt index 7a533883444e..51ebf149ea23 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,10 +14,13 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import android.os.UserHandle import com.android.systemui.plugins.qs.TileDetailsViewModel +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import kotlinx.coroutines.flow.StateFlow /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapter.kt index e607eae8f38d..f604de654085 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapter.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import android.content.Context import android.os.UserHandle @@ -31,6 +31,10 @@ import com.android.systemui.qs.QSHost import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelFactory.kt index 7f475f31b940..7404710f7e4d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelFactory.kt @@ -14,26 +14,25 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.UiBackground import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.TileDetailsViewModel import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics -import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent -import com.android.systemui.qs.tiles.impl.custom.di.QSTileConfigModule -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel -import com.android.systemui.qs.tiles.impl.di.QSTileComponent -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.QSTileCoroutineScopeFactory +import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics +import com.android.systemui.qs.tiles.base.ui.model.QSTileComponent +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel +import com.android.systemui.qs.tiles.impl.custom.shared.model.QSTileConfigModule +import com.android.systemui.qs.tiles.impl.custom.ui.model.CustomTileComponent import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.time.SystemClock import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImpl.kt index 3866c17b655f..f8723e422fe3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImpl.kt @@ -14,26 +14,26 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel +import android.annotation.SuppressLint import android.os.UserHandle import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.Dumpable import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.TileDetailsViewModel -import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.kotlin.throttle import com.android.systemui.util.time.SystemClock @@ -89,8 +89,10 @@ class QSTileViewModelImpl<DATA_TYPE>( private val users: MutableStateFlow<UserHandle> = MutableStateFlow(userRepository.getSelectedUserInfo().userHandle) + @SuppressLint("SharedFlowCreation") private val userInputs: MutableSharedFlow<QSTileUserAction> = MutableSharedFlow() + @SuppressLint("SharedFlowCreation") private val forceUpdates: MutableSharedFlow<Unit> = MutableSharedFlow() private val spec get() = config.tileSpec diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/StubQSTileViewModel.kt index bdd5c73779cf..304b8042aa83 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/StubQSTileViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,9 +14,12 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import android.os.UserHandle +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import kotlinx.coroutines.flow.StateFlow object StubQSTileViewModel : QSTileViewModel { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt index fb63bea4fb9f..8dc73e351703 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt @@ -19,7 +19,7 @@ package com.android.systemui.qs.tiles.dialog import android.content.Intent import android.provider.Settings import com.android.systemui.plugins.qs.TileDetailsViewModel -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler import com.android.systemui.statusbar.connectivity.AccessPointController import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt index 4f01a04fb742..63dd9b31326c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt @@ -17,8 +17,8 @@ package com.android.systemui.qs.tiles.impl.airplane.domain.interactor import android.os.UserHandle -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository import javax.inject.Inject @@ -29,13 +29,12 @@ import kotlinx.coroutines.flow.map /** Observes airplane mode state changes providing the [AirplaneModeTileModel]. */ class AirplaneModeTileDataInteractor @Inject -constructor( - private val airplaneModeRepository: AirplaneModeRepository, -) : QSTileDataInteractor<AirplaneModeTileModel> { +constructor(private val airplaneModeRepository: AirplaneModeRepository) : + QSTileDataInteractor<AirplaneModeTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<AirplaneModeTileModel> = airplaneModeRepository.isAirplaneMode.map { AirplaneModeTileModel(it) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt index 50532918b170..e86d95150139 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt @@ -19,11 +19,11 @@ package com.android.systemui.qs.tiles.impl.airplane.domain.interactor import android.content.Intent import android.provider.Settings import android.telephony.TelephonyManager -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor import javax.inject.Inject @@ -54,7 +54,7 @@ constructor( is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS) + Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapper.kt index 80d429ce2716..b0b7b4e2659b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,21 +14,21 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.airplane.domain +package com.android.systemui.qs.tiles.impl.airplane.ui.mapper import android.content.res.Resources import android.content.res.Resources.Theme import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject /** Maps [AirplaneModeTileModel] to [QSTileState]. */ -class AirplaneModeMapper +class AirplaneModeTileMapper @Inject constructor(@ShadeDisplayAware private val resources: Resources, val theme: Theme) : QSTileDataToStateMapper<AirplaneModeTileModel> { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt index 51cd501c0c80..1f113d9bddd4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt @@ -18,8 +18,8 @@ package com.android.systemui.qs.tiles.impl.alarm.domain.interactor import android.os.UserHandle import com.android.systemui.common.coroutine.ConflatedCallbackFlow -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel import com.android.systemui.statusbar.policy.NextAlarmController import com.android.systemui.util.time.DateFormatUtil @@ -33,12 +33,12 @@ class AlarmTileDataInteractor @Inject constructor( private val alarmController: NextAlarmController, - private val dateFormatUtil: DateFormatUtil + private val dateFormatUtil: DateFormatUtil, ) : QSTileDataInteractor<AlarmTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<AlarmTileModel> = ConflatedCallbackFlow.conflatedCallbackFlow { val alarmCallback = diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt index 79fcd3721877..f6fcf255cc4e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt @@ -18,19 +18,18 @@ package com.android.systemui.qs.tiles.impl.alarm.domain.interactor import android.content.Intent import android.provider.AlarmClock -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject /** Handles alarm tile clicks. */ class AlarmTileUserActionInteractor @Inject -constructor( - private val inputHandler: QSTileIntentUserInputHandler, -) : QSTileUserActionInteractor<AlarmTileModel> { +constructor(private val inputHandler: QSTileIntentUserInputHandler) : + QSTileUserActionInteractor<AlarmTileModel> { override suspend fun handleInput(input: QSTileInput<AlarmTileModel>): Unit = with(input) { when (action) { @@ -44,7 +43,7 @@ constructor( } else { inputHandler.handle( action.expandable, - Intent(AlarmClock.ACTION_SHOW_ALARMS) + Intent(AlarmClock.ACTION_SHOW_ALARMS), ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapper.kt index d56d9944dbb8..8a726adcd695 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.alarm.domain +package com.android.systemui.qs.tiles.impl.alarm.ui.mapper import android.content.res.Resources import android.content.res.Resources.Theme import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.time.SystemClock diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt index 22bbbbb62019..ed55449c7a9d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt @@ -18,11 +18,10 @@ package com.android.systemui.qs.tiles.impl.battery.domain.interactor import android.os.UserHandle import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel import com.android.systemui.statusbar.policy.BatteryController -import com.android.systemui.util.kotlin.combine import com.android.systemui.util.kotlin.getBatteryLevel import com.android.systemui.util.kotlin.isBatteryPowerSaveEnabled import com.android.systemui.util.kotlin.isDevicePluggedIn @@ -44,7 +43,7 @@ constructor( override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<BatterySaverTileModel> = combine( batteryController.isDevicePluggedIn().distinctUntilChanged().flowOn(bgCoroutineContext), @@ -56,8 +55,8 @@ constructor( ) { isPluggedIn: Boolean, isPowerSaverEnabled: Boolean, - _, // we are only interested in battery level change, not the actual level - -> + _ // we are only interested in battery level change, not the actual level + -> BatterySaverTileModel.Standard(isPluggedIn, isPowerSaverEnabled) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt index 3bbb9aa8505c..2eb05a2461f0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt @@ -18,11 +18,11 @@ package com.android.systemui.qs.tiles.impl.battery.domain.interactor import android.content.Intent import android.provider.Settings -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.BatteryController import javax.inject.Inject @@ -31,7 +31,7 @@ class BatterySaverTileUserActionInteractor @Inject constructor( private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler, - private val batteryController: BatteryController + private val batteryController: BatteryController, ) : QSTileUserActionInteractor<BatterySaverTileModel> { override suspend fun handleInput(input: QSTileInput<BatterySaverTileModel>) = @@ -45,7 +45,7 @@ constructor( is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS) + Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapper.kt index 72759c5bb066..7bc3d2bfc809 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.battery.ui +package com.android.systemui.qs.tiles.impl.battery.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt index cd33d451ba81..1d173fcebfac 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt @@ -18,8 +18,8 @@ package com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor import android.os.UserHandle import com.android.systemui.accessibility.data.repository.ColorCorrectionRepository -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -29,15 +29,15 @@ import kotlinx.coroutines.flow.map /** Observes color correction state changes providing the [ColorCorrectionTileModel]. */ class ColorCorrectionTileDataInteractor @Inject -constructor( - private val colorCorrectionRepository: ColorCorrectionRepository, -) : QSTileDataInteractor<ColorCorrectionTileModel> { +constructor(private val colorCorrectionRepository: ColorCorrectionRepository) : + QSTileDataInteractor<ColorCorrectionTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<ColorCorrectionTileModel> { return colorCorrectionRepository.isEnabled(user).map { ColorCorrectionTileModel(it) } } + override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt index b774643eb21d..dea1f5ca8c1b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt @@ -20,11 +20,11 @@ import android.content.Intent import android.provider.Settings import com.android.systemui.accessibility.data.repository.ColorCorrectionRepository import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject /** Handles color correction tile clicks. */ diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapper.kt index e5a0fe8ed048..93d81f0aa508 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.colorcorrection.domain +package com.android.systemui.qs.tiles.impl.colorcorrection.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/entity/CustomTileDefaults.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/model/CustomTileDefaults.kt index dfeb65b7c5aa..40151063ac9c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/entity/CustomTileDefaults.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/model/CustomTileDefaults.kt @@ -14,15 +14,13 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.data.entity +package com.android.systemui.qs.tiles.impl.custom.data.model import android.graphics.drawable.Icon sealed interface CustomTileDefaults { data object Error : CustomTileDefaults - data class Result( - val icon: Icon, - val label: CharSequence, - ) : CustomTileDefaults + + data class Result(val icon: Icon, val label: CharSequence) : CustomTileDefaults } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt index 32fb1d18724d..34894f52a0be 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt @@ -24,8 +24,8 @@ import android.graphics.drawable.Icon import android.os.UserHandle import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -58,11 +58,7 @@ interface CustomTileDefaultsRepository { * * Listen to [defaults] to get the loaded result */ - fun requestNewDefaults( - user: UserHandle, - componentName: ComponentName, - force: Boolean = false, - ) + fun requestNewDefaults(user: UserHandle, componentName: ComponentName, force: Boolean = false) } @QSTileScope @@ -77,7 +73,7 @@ constructor( private val defaultsRequests = MutableSharedFlow<DefaultsRequest>( replay = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST + onBufferOverflow = BufferOverflow.DROP_OLDEST, ) private val defaults: SharedFlow<DefaultsResult> = @@ -106,7 +102,7 @@ constructor( private suspend fun loadDefaults( user: UserHandle, - componentName: ComponentName + componentName: ComponentName, ): CustomTileDefaults = withContext(backgroundDispatcher) { try { @@ -120,16 +116,14 @@ constructor( CustomTileDefaults.Result( Icon.createWithResource(componentName.packageName, iconRes), - info.loadLabel(userContext.packageManager) + info.loadLabel(userContext.packageManager), ) } catch (e: PackageManager.NameNotFoundException) { CustomTileDefaults.Error } } - private fun ComponentName.getServiceInfo( - packageManager: PackageManager, - ): ServiceInfo { + private fun ComponentName.getServiceInfo(packageManager: PackageManager): ServiceInfo { val isSystemApp = packageManager.getApplicationInfo(packageName, 0).isSystemApp var flags = (PackageManager.MATCH_DIRECT_BOOT_UNAWARE or PackageManager.MATCH_DIRECT_BOOT_AWARE) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt index cd4938f01b63..da811a3c494f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt @@ -23,12 +23,12 @@ import android.content.Intent import android.content.IntentFilter import android.os.UserHandle import androidx.annotation.GuardedBy -import com.android.systemui.common.coroutine.ConflatedCallbackFlow -import com.android.systemui.dagger.qualifiers.Application +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope import com.android.systemui.shade.ShadeDisplayAware +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope @@ -40,7 +40,6 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.shareIn -import com.android.app.tracing.coroutines.launchTraced as launch interface CustomTilePackageUpdatesRepository { @@ -79,7 +78,7 @@ constructor( "RegisterReceiverViaContext", ) private fun createPackageChangesFlowForUser(user: UserHandle): Flow<Unit> = - ConflatedCallbackFlow.conflatedCallbackFlow { + conflatedCallbackFlow { val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt index 0aaea8fc0a50..aabe7a9365ba 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt @@ -27,10 +27,10 @@ import com.android.systemui.qs.external.CustomTileStatePersister import com.android.systemui.qs.external.PackageManagerAdapter import com.android.systemui.qs.external.TileServiceKey import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.impl.custom.commons.copy -import com.android.systemui.qs.tiles.impl.custom.commons.setFrom -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults +import com.android.systemui.qs.tiles.impl.custom.shared.model.copy +import com.android.systemui.qs.tiles.impl.custom.shared.model.setFrom import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.channels.BufferOverflow @@ -78,11 +78,7 @@ interface CustomTileRepository { * [user] differs from the cached one. [isPersistable] tile will be persisted to be possibly * loaded when the [restoreForTheUserIfNeeded]. */ - suspend fun updateWithTile( - user: UserHandle, - newTile: Tile, - isPersistable: Boolean, - ) + suspend fun updateWithTile(user: UserHandle, newTile: Tile, isPersistable: Boolean) /** * Updates tile with the values from [defaults]. Overwrites the current cache when [user] @@ -114,11 +110,7 @@ constructor( if (isPersistable && getCurrentTileWithUser()?.user != user) { withContext(backgroundContext) { customTileStatePersister.readState(user.getKey())?.let { - updateWithTile( - user, - it, - true, - ) + updateWithTile(user, it, true) } } } @@ -137,11 +129,8 @@ constructor( } } - override suspend fun updateWithTile( - user: UserHandle, - newTile: Tile, - isPersistable: Boolean, - ) = updateTile(user, isPersistable) { setFrom(newTile) } + override suspend fun updateWithTile(user: UserHandle, newTile: Tile, isPersistable: Boolean) = + updateTile(user, isPersistable) { setFrom(newTile) } override suspend fun updateWithDefaults( user: UserHandle, @@ -182,7 +171,7 @@ constructor( packageManagerAdapter.getServiceInfo( tileSpec.componentName, META_DATA_QUERY_FLAGS, - getCurrentTileWithUser()?.user?.identifier ?: UserHandle.USER_CURRENT + getCurrentTileWithUser()?.user?.identifier ?: UserHandle.USER_CURRENT, ) info?.metaData?.getBoolean(TileService.META_DATA_TOGGLEABLE_TILE, false) == true } catch (e: RemoteException) { @@ -193,7 +182,7 @@ constructor( private suspend fun updateTile( user: UserHandle, isPersistable: Boolean, - update: Tile.() -> Unit + update: Tile.() -> Unit, ): Unit = tileUpdateMutex.withLock { val currentTileWithUser = getCurrentTileWithUser() diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt index 0b0f2feaa909..e64675f81257 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt @@ -20,14 +20,14 @@ import android.os.UserHandle import android.service.quicksettings.Tile import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt index 6f1cb3cc2675..c587e3a11edf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt @@ -18,11 +18,12 @@ package com.android.systemui.qs.tiles.impl.custom.domain.interactor import android.os.UserHandle import android.service.quicksettings.Tile +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepository -import com.android.systemui.qs.tiles.impl.di.QSTileScope import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope @@ -34,7 +35,6 @@ import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import com.android.app.tracing.coroutines.launchTraced as launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -100,7 +100,7 @@ constructor( launchUpdates(user) customTileRepository.restoreForTheUserIfNeeded( user, - customTileRepository.isTileActive() + customTileRepository.isTileActive(), ) // Suspend to make sure it gets the tile from one of the sources: restoration, defaults, // or diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt index c0fc93fc914b..56fd325fe6d2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt @@ -31,8 +31,8 @@ import com.android.systemui.qs.external.CustomTileInterface import com.android.systemui.qs.external.TileServiceManager import com.android.systemui.qs.external.TileServices import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope import com.android.systemui.user.data.repository.UserRepository import dagger.Lazy import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt index 1153b5c67261..df2759ab9de1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt @@ -34,13 +34,13 @@ import androidx.annotation.GuardedBy import com.android.systemui.animation.Expandable import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.logging.QSTileLogger -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel -import com.android.systemui.qs.tiles.impl.di.QSTileScope -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel import com.android.systemui.settings.DisplayTracker import com.android.systemui.shade.ShadeDisplayAware import java.util.concurrent.atomic.AtomicReference @@ -80,10 +80,7 @@ constructor( qsTileLogger.logCustomTileUserActionDelivered(tileSpec) } - private suspend fun click( - expandable: Expandable?, - activityLaunchForClick: PendingIntent?, - ) { + private suspend fun click(expandable: Expandable?, activityLaunchForClick: PendingIntent?) { grantToken() try { // Bind active tile to deliver user action @@ -133,7 +130,7 @@ constructor( token, WindowManager.LayoutParams.TYPE_QS_DIALOG, displayTracker.defaultDisplayId, - null /* options */ + null, /* options */ ) } catch (e: RemoteException) { qsTileLogger.logError(tileSpec, "Failed to grant a window token", e) @@ -147,7 +144,7 @@ constructor( user: UserHandle, expandable: Expandable?, componentName: ComponentName, - state: Int + state: Int, ) { val resolvedIntent: Intent? = resolveIntent( @@ -166,7 +163,7 @@ constructor( Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) .setData( Uri.fromParts(IntentFilter.SCHEME_PACKAGE, componentName.packageName, null) - ) + ), ) } else { qsTileIntentUserInputHandler.handle(expandable, resolvedIntent) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/entity/CustomTileDataModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/model/CustomTileDataModel.kt index 5b6ff1e033fb..4393e9e1bb63 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/entity/CustomTileDataModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/model/CustomTileDataModel.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.domain.entity +package com.android.systemui.qs.tiles.impl.custom.domain.model import android.content.ComponentName import android.graphics.drawable.Icon diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/QSTileConfigModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/QSTileConfigModule.kt index 558fb64e3ef8..c9508889ff85 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/QSTileConfigModule.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/QSTileConfigModule.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.di +package com.android.systemui.qs.tiles.impl.custom.shared.model import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/TileExt.kt index 869f6f321d21..022894e2e5d2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/TileExt.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.commons +package com.android.systemui.qs.tiles.impl.custom.shared.model import android.service.quicksettings.Tile diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapper.kt index c446865f31af..dfaaea1e7d86 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.domain +package com.android.systemui.qs.tiles.impl.custom.ui.mapper import android.annotation.SuppressLint import android.app.IUriGrantsManager @@ -26,10 +26,10 @@ import android.widget.Button import android.widget.Switch import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject @@ -38,9 +38,8 @@ class CustomTileMapper @Inject constructor( @ShadeDisplayAware private val context: Context, - private val uriGrantsManager: IUriGrantsManager -) : - QSTileDataToStateMapper<CustomTileDataModel> { + private val uriGrantsManager: IUriGrantsManager, +) : QSTileDataToStateMapper<CustomTileDataModel> { override fun map(config: QSTileConfig, data: CustomTileDataModel): QSTileState { val userContext = diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileComponent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileComponent.kt index 7b099c2cb0c6..4f230334c427 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileComponent.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,14 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.di +package com.android.systemui.qs.tiles.impl.custom.ui.model +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope +import com.android.systemui.qs.tiles.base.ui.model.QSTileComponent import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileInteractor import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileServiceInteractor -import com.android.systemui.qs.tiles.impl.di.QSTileComponent -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel +import com.android.systemui.qs.tiles.impl.custom.shared.model.QSTileConfigModule import dagger.Subcomponent @QSTileScope diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileModule.kt index 196fa12cacc9..ee7908af6c84 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,23 +14,23 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom.di +package com.android.systemui.qs.tiles.impl.custom.ui.model -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileCoroutineScopeFactory +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileCoroutineScopeFactory +import com.android.systemui.qs.tiles.base.shared.model.QSTileScope +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepositoryImpl import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepositoryImpl import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepositoryImpl -import com.android.systemui.qs.tiles.impl.custom.domain.CustomTileMapper -import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileDataInteractor import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileUserActionInteractor -import com.android.systemui.qs.tiles.impl.di.QSTileScope +import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel +import com.android.systemui.qs.tiles.impl.custom.ui.mapper.CustomTileMapper import dagger.Binds import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt index 38eb5947bd71..9720d1549a4c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt @@ -17,11 +17,11 @@ package com.android.systemui.qs.tiles.impl.flashlight.domain.interactor import android.os.UserHandle -import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel import com.android.systemui.statusbar.policy.FlashlightController +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -30,22 +30,23 @@ import kotlinx.coroutines.flow.flowOf /** Observes flashlight state changes providing the [FlashlightTileModel]. */ class FlashlightTileDataInteractor @Inject -constructor( - private val flashlightController: FlashlightController, -) : QSTileDataInteractor<FlashlightTileModel> { +constructor(private val flashlightController: FlashlightController) : + QSTileDataInteractor<FlashlightTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<FlashlightTileModel> = conflatedCallbackFlow { val callback = object : FlashlightController.FlashlightListener { override fun onFlashlightChanged(enabled: Boolean) { trySend(FlashlightTileModel.FlashlightAvailable(enabled)) } + override fun onFlashlightError() { trySend(FlashlightTileModel.FlashlightAvailable(false)) } + override fun onFlashlightAvailabilityChanged(available: Boolean) { trySend( if (available) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt index 13afc15d17ef..8a76b2a61677 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt @@ -17,19 +17,18 @@ package com.android.systemui.qs.tiles.impl.flashlight.domain.interactor import android.app.ActivityManager -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.FlashlightController import javax.inject.Inject /** Handles flashlight tile clicks. */ class FlashlightTileUserActionInteractor @Inject -constructor( - private val flashlightController: FlashlightController, -) : QSTileUserActionInteractor<FlashlightTileModel> { +constructor(private val flashlightController: FlashlightController) : + QSTileUserActionInteractor<FlashlightTileModel> { override suspend fun handleInput(input: QSTileInput<FlashlightTileModel>) = with(input) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapper.kt index 32ccba6f1fa5..0be4a9fffe1b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapper.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.flashlight.domain +package com.android.systemui.qs.tiles.impl.flashlight.ui.mapper import android.content.res.Resources import android.content.res.Resources.Theme import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt index 745e6a301689..3464741ffe9c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt @@ -17,8 +17,8 @@ package com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor import android.os.UserHandle -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -29,7 +29,7 @@ class FontScalingTileDataInteractor @Inject constructor() : QSTileDataInteractor<FontScalingTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<FontScalingTileModel> = flowOf(FontScalingTileModel) override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt index 0ebb51e722af..65db0f9fd8b1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt @@ -25,11 +25,11 @@ import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.ActivityStarter import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.policy.KeyguardStateController import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapper.kt index c571b136e18b..659e1fe6a81d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.fontscaling.domain +package com.android.systemui.qs.tiles.impl.fontscaling.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt index 33b7feb49b09..50ea30dc8011 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt @@ -19,8 +19,8 @@ package com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor import android.os.UserHandle import com.android.systemui.accessibility.hearingaid.HearingDevicesChecker import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel import com.android.systemui.statusbar.policy.BluetoothController import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt index 268efcef9062..049d0618875e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt @@ -22,11 +22,11 @@ import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogManager import com.android.systemui.accessibility.hearingaid.HearingDevicesUiEventLogger.Companion.LAUNCH_SOURCE_QS_TILE import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.withContext diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapper.kt index 12f71491c7b4..d89c535b2c67 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.hearingdevices.domain +package com.android.systemui.qs.tiles.impl.hearingdevices.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt index 871c051722c6..786ac47a0190 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt @@ -24,8 +24,8 @@ import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Text import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt index 0431e36fef6a..7fd282c63d84 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt @@ -19,12 +19,12 @@ package com.android.systemui.qs.tiles.impl.internet.domain.interactor import android.content.Intent import android.provider.Settings import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.dialog.InternetDialogManager import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.connectivity.AccessPointController import javax.inject.Inject import kotlin.coroutines.CoroutineContext diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapper.kt index 8d5880554277..a96ad38921a5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapper.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.internet.domain +package com.android.systemui.qs.tiles.impl.internet.ui.mapper import android.content.Context import android.content.res.Resources @@ -25,10 +25,10 @@ import com.android.systemui.common.shared.model.ContentDescription.Companion.loa import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text.Companion.loadText import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileIconModel diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt index 7f3dd3e17b79..fea9e7eb3bda 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt @@ -18,8 +18,8 @@ package com.android.systemui.qs.tiles.impl.inversion.domain.interactor import android.os.UserHandle import com.android.systemui.accessibility.data.repository.ColorInversionRepository -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -29,15 +29,15 @@ import kotlinx.coroutines.flow.map /** Observes color inversion state changes providing the [ColorInversionTileModel]. */ class ColorInversionTileDataInteractor @Inject -constructor( - private val colorInversionRepository: ColorInversionRepository, -) : QSTileDataInteractor<ColorInversionTileModel> { +constructor(private val colorInversionRepository: ColorInversionRepository) : + QSTileDataInteractor<ColorInversionTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<ColorInversionTileModel> { return colorInversionRepository.isEnabled(user).map { ColorInversionTileModel(it) } } + override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt index f78349718697..12530bc8361c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt @@ -20,11 +20,11 @@ import android.content.Intent import android.provider.Settings import com.android.systemui.accessibility.data.repository.ColorInversionRepository import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject /** Handles color inversion tile clicks. */ diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapper.kt index 05590e803ffa..868abc045ad6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapper.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.inversion.domain +package com.android.systemui.qs.tiles.impl.inversion.ui.mapper import android.content.res.Resources import android.content.res.Resources.Theme import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/data/model/IssueRecordingModel.kt index 260729b6a868..704102b25ce2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/data/model/IssueRecordingModel.kt @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.data.model @JvmInline value class IssueRecordingModel(val isRecording: Boolean) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractor.kt index 09a6ce8e5ec0..95fe191aad3f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractor.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,13 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.domain.interactor import android.os.UserHandle import com.android.systemui.Flags import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel import com.android.systemui.recordissue.IssueRecordingState import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractor.kt index fceee5a3379e..7182a37b7064 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractor.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.domain.interactor import android.app.AlertDialog import android.app.BroadcastOptions @@ -30,9 +30,10 @@ import com.android.systemui.plugins.ActivityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.DELAY_MS import com.android.systemui.qs.tiles.INTERVAL_MS -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel import com.android.systemui.recordissue.IssueRecordingService.Companion.getStartIntent import com.android.systemui.recordissue.IssueRecordingService.Companion.getStopIntent import com.android.systemui.recordissue.IssueRecordingState @@ -47,8 +48,6 @@ import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.withContext -private const val TAG = "IssueRecordingActionInteractor" - class IssueRecordingUserActionInteractor @Inject constructor( @@ -128,4 +127,8 @@ constructor( action, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) + + companion object { + private const val TAG = "IssueRecordingUserActionInteractor" + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapper.kt index afb137e1e92f..bd51bbeed4b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,14 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.irecording +package com.android.systemui.qs.tiles.impl.irecording.ui.mapper import android.content.res.Resources import android.content.res.Resources.Theme import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt index bd2f2c987ccf..052d062364cf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt @@ -17,8 +17,8 @@ package com.android.systemui.qs.tiles.impl.location.domain.interactor import android.os.UserHandle -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel import com.android.systemui.statusbar.policy.LocationController import com.android.systemui.util.kotlin.isLocationEnabledFlow @@ -30,13 +30,12 @@ import kotlinx.coroutines.flow.map /** Observes location state changes providing the [LocationTileModel]. */ class LocationTileDataInteractor @Inject -constructor( - private val locationController: LocationController, -) : QSTileDataInteractor<LocationTileModel> { +constructor(private val locationController: LocationController) : + QSTileDataInteractor<LocationTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<LocationTileModel> = locationController.isLocationEnabledFlow().map { LocationTileModel(it) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt index d46bcfc3b947..f5d1400c9c7a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt @@ -18,21 +18,21 @@ package com.android.systemui.qs.tiles.impl.location.domain.interactor import android.content.Intent import android.provider.Settings +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.coroutines.newTracingContext import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.LocationController import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope -import com.android.app.tracing.coroutines.launchTraced as launch import kotlinx.coroutines.withContext /** Handles location tile clicks. */ @@ -68,7 +68,7 @@ constructor( is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) + Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapper.kt index ced5a4f099a2..d2c9116b0f24 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapper.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.location.domain +package com.android.systemui.qs.tiles.impl.location.ui.mapper import android.content.res.Resources import android.content.res.Resources.Theme import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt index b1ae3ba4381a..c3e7bea4a466 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt @@ -18,12 +18,14 @@ package com.android.systemui.qs.tiles.impl.modes.domain.interactor import android.content.Context import android.os.UserHandle +import android.text.TextUtils import com.android.app.tracing.coroutines.flow.flowName import com.android.settingslib.notification.modes.ZenMode +import com.android.settingslib.notification.modes.ZenModeDescriptions import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.modes.shared.ModesUi -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor @@ -44,6 +46,8 @@ constructor( @Background val bgDispatcher: CoroutineDispatcher, ) : QSTileDataInteractor<ModesDndTileModel> { + private val zenModeDescriptions = ZenModeDescriptions(context) + override fun tileData( user: UserHandle, triggers: Flow<DataUpdateTrigger>, @@ -65,7 +69,10 @@ constructor( fun getCurrentTileModel() = buildTileData(zenModeInteractor.getDndMode()) private fun buildTileData(dndMode: ZenMode): ModesDndTileModel { - return ModesDndTileModel(isActivated = dndMode.isActive) + return ModesDndTileModel( + isActivated = dndMode.isActive, + extraStatus = TextUtils.nullIfEmpty(zenModeDescriptions.getTriggerDescription(dndMode)), + ) } override fun availability(user: UserHandle): Flow<Boolean> = diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt index e8fcea070ede..012ae036cf47 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt @@ -24,11 +24,11 @@ import com.android.systemui.animation.Expandable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.qs.shared.QSSettingsPackageRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt index 479f61823912..e97985c6ab78 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt @@ -25,8 +25,8 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.modes.shared.ModesUi import com.android.systemui.modes.shared.ModesUiIcons import com.android.systemui.qs.tiles.ModesTile -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt index ab1326a8bafb..5240a1809b76 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt @@ -23,11 +23,11 @@ import com.android.systemui.animation.Expandable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.qs.flags.QSComposeFragment -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt index eab798897aa3..e13cc6592e9d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt @@ -16,4 +16,4 @@ package com.android.systemui.qs.tiles.impl.modes.domain.model -data class ModesDndTileModel(val isActivated: Boolean) +data class ModesDndTileModel(val isActivated: Boolean, val extraStatus: String?) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt index 4869b6f74554..632c572455e4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt @@ -19,10 +19,10 @@ package com.android.systemui.qs.tiles.impl.modes.ui import android.content.res.Resources import android.widget.Switch import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject @@ -49,11 +49,9 @@ constructor(@ShadeDisplayAware private val resources: Resources, val theme: Reso QSTileState.ActivationState.INACTIVE } label = resources.getString(R.string.quick_settings_dnd_label) - secondaryLabel = - resources.getString( - if (data.isActivated) R.string.zen_mode_on else R.string.zen_mode_off - ) + secondaryLabel = data.extraStatus contentDescription = label + stateDescription = data.extraStatus supportedActions = setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK) expandedAccessibilityClass = Switch::class diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapper.kt index 99ae3b8db709..4668350131a6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapper.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.modes.ui +package com.android.systemui.qs.tiles.impl.modes.ui.mapper import android.content.res.Resources import android.icu.text.MessageFormat import android.widget.Button -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import java.util.Locale diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt index e8e43e8fc749..f6f267fbce0e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt @@ -20,8 +20,8 @@ import android.content.Context import android.hardware.display.ColorDisplayManager import android.os.UserHandle import com.android.systemui.accessibility.data.repository.NightDisplayRepository -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.time.DateFormatUtil diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt index 7076a8f757fe..41739422ecb1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt @@ -22,12 +22,12 @@ import android.provider.Settings import com.android.systemui.accessibility.data.repository.NightDisplayRepository import com.android.systemui.accessibility.qs.QSAccessibilityModule import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.base.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject /** Handles night display tile clicks. */ @@ -52,7 +52,7 @@ constructor( is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS) + Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapper.kt index 16b36289ad95..3e478754d261 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.night.ui +package com.android.systemui.qs.tiles.impl.night.ui.mapper import android.content.res.Resources import android.service.quicksettings.Tile @@ -23,11 +23,11 @@ import androidx.annotation.StringRes import com.android.systemui.accessibility.qs.QSAccessibilityModule import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.base.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import java.time.DateTimeException diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt index a501b8561330..157da8a5f321 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt @@ -19,8 +19,8 @@ package com.android.systemui.qs.tiles.impl.notes.domain.interactor import android.os.UserHandle import com.android.systemui.Flags import com.android.systemui.notetask.NoteTaskEnabledKey -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt index df01d99df0df..527f9e841ea9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt @@ -20,15 +20,16 @@ import com.android.systemui.animation.Expandable import com.android.systemui.notetask.NoteTaskController import com.android.systemui.notetask.NoteTaskEntryPoint import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject class NotesTileUserActionInteractor -@Inject constructor( +@Inject +constructor( private val qsTileIntentUserInputHandler: QSTileIntentUserInputHandler, private val panelInteractor: PanelInteractor, private val noteTaskController: NoteTaskController, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapper.kt index ecdd71170cda..36b28dfac7c7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapper.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.notes.domain +package com.android.systemui.qs.tiles.impl.notes.ui.mapper import android.content.res.Resources import android.widget.Button import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt index 8c0fd2cd672a..39f39766fee6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt @@ -18,8 +18,8 @@ package com.android.systemui.qs.tiles.impl.onehanded.domain import android.os.UserHandle import com.android.systemui.accessibility.data.repository.OneHandedModeRepository -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel import com.android.wm.shell.onehanded.OneHanded import javax.inject.Inject @@ -30,16 +30,16 @@ import kotlinx.coroutines.flow.map /** Observes one handed mode state changes providing the [OneHandedModeTileModel]. */ class OneHandedModeTileDataInteractor @Inject -constructor( - private val oneHandedModeRepository: OneHandedModeRepository, -) : QSTileDataInteractor<OneHandedModeTileModel> { +constructor(private val oneHandedModeRepository: OneHandedModeRepository) : + QSTileDataInteractor<OneHandedModeTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<OneHandedModeTileModel> { return oneHandedModeRepository.isEnabled(user).map { OneHandedModeTileModel(it) } } + override fun availability(user: UserHandle): Flow<Boolean> = flowOf(OneHanded.sIsSupportOneHandedMode) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt index 0a0f0a668079..88f9d840012e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt @@ -19,11 +19,11 @@ package com.android.systemui.qs.tiles.impl.onehanded.domain import android.content.Intent import android.provider.Settings import com.android.systemui.accessibility.data.repository.OneHandedModeRepository -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject /** Handles one handed mode tile clicks. */ @@ -38,15 +38,12 @@ constructor( with(input) { when (action) { is QSTileUserAction.Click -> { - oneHandedModeRepository.setIsEnabled( - !data.isEnabled, - user, - ) + oneHandedModeRepository.setIsEnabled(!data.isEnabled, user) } is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_ONE_HANDED_SETTINGS) + Intent(Settings.ACTION_ONE_HANDED_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapper.kt index 5b3ea93ab1ae..ace36ce586de 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.onehanded.ui +package com.android.systemui.qs.tiles.impl.onehanded.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt index 233e913a27aa..0b4752bcaac4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt @@ -21,8 +21,8 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qrcodescanner.controller.QRCodeScannerController import com.android.systemui.qrcodescanner.controller.QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject @@ -44,7 +44,7 @@ constructor( ) : QSTileDataInteractor<QRCodeScannerTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<QRCodeScannerTileModel> = conflatedCallbackFlow { qrController.registerQRCodeScannerChangeObservers(DEFAULT_QR_CODE_SCANNER_CHANGE) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt index bb5df022dd1b..eb47d0b8fe91 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt @@ -16,19 +16,18 @@ package com.android.systemui.qs.tiles.impl.qr.domain.interactor -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import javax.inject.Inject /** Handles qr tile clicks. */ class QRCodeScannerTileUserActionInteractor @Inject -constructor( - private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler, -) : QSTileUserActionInteractor<QRCodeScannerTileModel> { +constructor(private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler) : + QSTileUserActionInteractor<QRCodeScannerTileModel> { override suspend fun handleInput(input: QSTileInput<QRCodeScannerTileModel>): Unit = with(input) { @@ -39,7 +38,7 @@ constructor( qsTileIntentUserActionHandler.handle( action.expandable, data.intent, - true + true, ) is QRCodeScannerTileModel.TemporarilyUnavailable -> {} // no-op } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapper.kt index 21e92d3a1972..120961b76493 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.qr.ui +package com.android.systemui.qs.tiles.impl.qr.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/model/QRCodeScannerModule.kt index ef1f8341cb15..c3c6be3f7410 100644 --- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/model/QRCodeScannerModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qrcodescanner.dagger +package com.android.systemui.qs.tiles.impl.qr.ui.model import com.android.systemui.Flags import com.android.systemui.qs.QsEventLogger @@ -22,16 +22,16 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.tiles.QRCodeScannerTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileDataInteractor import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileUserActionInteractor import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel -import com.android.systemui.qs.tiles.impl.qr.ui.QRCodeScannerTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.impl.qr.ui.mapper.QRCodeScannerTileMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module @@ -81,7 +81,7 @@ interface QRCodeScannerModule { factory: QSTileViewModelFactory.Static<QRCodeScannerTileModel>, mapper: QRCodeScannerTileMapper, stateInteractor: QRCodeScannerTileDataInteractor, - userActionInteractor: QRCodeScannerTileUserActionInteractor + userActionInteractor: QRCodeScannerTileUserActionInteractor, ): QSTileViewModel = if (Flags.qsNewTilesFuture()) factory.create( diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt index 536c5f1d17cf..46ed2ffd0996 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt @@ -20,8 +20,8 @@ import android.os.UserHandle import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.ReduceBrightColorsController import com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel import com.android.systemui.util.kotlin.isEnabled import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt index eff5f8f949c2..0bc3dec77853 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt @@ -21,11 +21,11 @@ import android.content.res.Resources import android.provider.Settings import com.android.systemui.accessibility.extradim.ExtraDimDialogManager import com.android.systemui.qs.ReduceBrightColorsController -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapper.kt index 66759cdfd1a6..2e74399c008f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapper.kt @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.reducebrightness.ui +package com.android.systemui.qs.tiles.impl.reducebrightness.ui.mapper import android.content.res.Resources import android.service.quicksettings.Tile import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt index 7f17a3a7481a..f89154d9428a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt @@ -22,8 +22,8 @@ import android.content.res.Resources import android.os.UserHandle import com.android.systemui.camera.data.repository.CameraAutoRotateRepository import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepository -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.BatteryController diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt index 65712c75516f..71aaa93db5ff 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt @@ -18,11 +18,11 @@ package com.android.systemui.qs.tiles.impl.rotation.domain.interactor import android.content.Intent import android.provider.Settings -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.RotationLockController import javax.inject.Inject @@ -43,7 +43,7 @@ constructor( is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS) + Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt index 000c7025e32b..d1db49929c0b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt @@ -19,10 +19,10 @@ package com.android.systemui.qs.tiles.impl.rotation.ui.mapper import android.content.res.Resources import android.hardware.devicestate.DeviceStateManager import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.DevicePostureController diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt index 91e049b68c06..1c19444a93f9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt @@ -18,8 +18,8 @@ package com.android.systemui.qs.tiles.impl.saver.domain.interactor import android.os.UserHandle import com.android.systemui.common.coroutine.ConflatedCallbackFlow -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel import com.android.systemui.statusbar.policy.DataSaverController import javax.inject.Inject @@ -30,13 +30,12 @@ import kotlinx.coroutines.flow.flowOf /** Observes data saver state changes providing the [DataSaverTileModel]. */ class DataSaverTileDataInteractor @Inject -constructor( - private val dataSaverController: DataSaverController, -) : QSTileDataInteractor<DataSaverTileModel> { +constructor(private val dataSaverController: DataSaverController) : + QSTileDataInteractor<DataSaverTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<DataSaverTileModel> = ConflatedCallbackFlow.conflatedCallbackFlow { val initialValue = dataSaverController.isDataSaverEnabled diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt index 63a9f594b05c..16fb9f7aeb72 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt @@ -24,12 +24,12 @@ import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.saver.domain.DataSaverDialogDelegate import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.settings.UserFileManager import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapper.kt index 1d5cf29f2462..e15c098451cb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.saver.domain +package com.android.systemui.qs.tiles.impl.saver.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt index 597825c7611c..7e2f1bd52a52 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt @@ -17,8 +17,8 @@ package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor import android.os.UserHandle -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository import javax.inject.Inject @@ -28,13 +28,12 @@ import kotlinx.coroutines.flow.flowOf /** Observes screen record state changes providing the [ScreenRecordModel]. */ class ScreenRecordTileDataInteractor @Inject -constructor( - private val screenRecordRepository: ScreenRecordRepository, -) : QSTileDataInteractor<ScreenRecordModel> { +constructor(private val screenRecordRepository: ScreenRecordRepository) : + QSTileDataInteractor<ScreenRecordModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<ScreenRecordModel> = screenRecordRepository.screenRecordState override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt index 94534479db57..b7dc63286454 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt @@ -28,9 +28,9 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger import com.android.systemui.plugins.ActivityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/mapper/ScreenRecordTileMapper.kt index 0a61e3cbe616..b0c9d1224ce5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/mapper/ScreenRecordTileMapper.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.screenrecord.domain.ui +package com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.mapper import android.content.res.Resources import android.text.TextUtils import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.res.R import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.shade.ShadeDisplayAware diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractor.kt index a8e9c5663f39..f033e6ac0be4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractor.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.sensorprivacy +package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor import android.hardware.SensorPrivacyManager.Sensors.CAMERA import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE @@ -22,12 +22,12 @@ import android.hardware.SensorPrivacyManager.Sensors.Sensor import android.os.UserHandle import android.provider.DeviceConfig import android.util.Log -import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -55,7 +55,7 @@ constructor( override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<SensorPrivacyToggleTileModel> = conflatedCallbackFlow { val callback = @@ -85,14 +85,14 @@ constructor( return@withContext DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_PRIVACY, deviceConfigName, - true + true, ) } catch (exception: IllegalArgumentException) { Log.w( TAG, "isDeviceConfigSet for sensorId $sensorId: " + "Defaulting to true due to exception. ", - exception + exception, ) return@withContext true } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractor.kt index d7f64d11a4fd..decf432169b0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractor.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.sensorprivacy.domain +package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor import android.content.Intent import android.hardware.SensorPrivacyManager.Sensors.Sensor @@ -23,11 +23,11 @@ import android.provider.Settings import android.safetycenter.SafetyCenterManager import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController import dagger.assisted.Assisted import dagger.assisted.AssistedFactory diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapper.kt index f54f46c01dee..e9d5f528dc27 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,14 +14,15 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.sensorprivacy.ui +package com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper import android.content.res.Resources import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import dagger.assisted.Assisted diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/model/SensorPrivacyTileResources.kt index 2a9fd07a67cb..e65ae00f6938 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/model/SensorPrivacyTileResources.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,12 +14,13 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.sensorprivacy.ui +package com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model import com.android.systemui.res.R sealed interface SensorPrivacyTileResources { fun getIconRes(isBlocked: Boolean): Int + fun getTileLabelRes(): Int data object CameraPrivacyTileResources : SensorPrivacyTileResources { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt index 925b91326a25..17c2f83b6f70 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt @@ -21,9 +21,9 @@ import android.content.Context import android.content.res.Configuration import android.os.UserHandle import com.android.systemui.common.coroutine.ConflatedCallbackFlow -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor -import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger +import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt index 889782831b70..8af5fedff46a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt @@ -20,11 +20,11 @@ import android.app.UiModeManager import android.content.Intent import android.provider.Settings import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor -import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.withContext @@ -51,7 +51,7 @@ constructor( is QSTileUserAction.LongClick -> { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_DARK_THEME_SETTINGS) + Intent(Settings.ACTION_DARK_THEME_SETTINGS), ) } is QSTileUserAction.ToggleClick -> {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/model/UiModeNightTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/model/UiModeNightTileModel.kt index 4fa1306d988d..edb899be5c57 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/model/UiModeNightTileModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/model/UiModeNightTileModel.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.uimodenight.domain.model +package com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model import java.time.LocalTime @@ -31,5 +31,5 @@ data class UiModeNightTileModel( val nightModeCustomType: Int, val is24HourFormat: Boolean, val customNightModeEnd: LocalTime, - val customNightModeStart: LocalTime + val customNightModeStart: LocalTime, ) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapper.kt index 5933d65bc61f..91c045101182 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.uimodenight.domain +package com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper import android.app.UiModeManager import android.content.res.Resources import android.content.res.Resources.Theme import android.text.TextUtils import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper -import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import java.time.LocalTime diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt index a2a9e87a5981..eabeb5d348f7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt @@ -17,8 +17,8 @@ package com.android.systemui.qs.tiles.impl.work.domain.interactor import android.os.UserHandle -import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger -import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel import com.android.systemui.statusbar.phone.ManagedProfileController import com.android.systemui.util.kotlin.hasActiveWorkProfile @@ -29,12 +29,11 @@ import kotlinx.coroutines.flow.map /** Observes data saver state changes providing the [WorkModeTileModel]. */ class WorkModeTileDataInteractor @Inject -constructor( - private val profileController: ManagedProfileController, -) : QSTileDataInteractor<WorkModeTileModel> { +constructor(private val profileController: ManagedProfileController) : + QSTileDataInteractor<WorkModeTileModel> { override fun tileData( user: UserHandle, - triggers: Flow<DataUpdateTrigger> + triggers: Flow<DataUpdateTrigger>, ): Flow<WorkModeTileModel> = profileController.hasActiveWorkProfile.map { hasActiveWorkProfile: Boolean -> if (hasActiveWorkProfile) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt index 45ae09eaef92..42cc996fc722 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt @@ -18,11 +18,11 @@ package com.android.systemui.qs.tiles.impl.work.domain.interactor import android.content.Intent import android.provider.Settings -import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.interactor.QSTileInput -import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.phone.ManagedProfileController import javax.inject.Inject @@ -45,7 +45,7 @@ constructor( if (data is WorkModeTileModel.HasActiveProfile) { qsTileIntentUserActionHandler.handle( action.expandable, - Intent(Settings.ACTION_MANAGED_PROFILE_SETTINGS) + Intent(Settings.ACTION_MANAGED_PROFILE_SETTINGS), ) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapper.kt index 5b462ba074ec..a67c76d4fb78 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapper.kt @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.work.ui +package com.android.systemui.qs.tiles.impl.work.ui.mapper import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_WORK_PROFILE_LABEL import android.content.res.Resources import android.service.quicksettings.Tile import com.android.systemui.common.shared.model.Icon -import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt index bc15bbb5e57d..263ef09ea767 100644 --- a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt @@ -20,6 +20,8 @@ import android.content.Context import android.hardware.devicestate.DeviceStateManager import android.hardware.devicestate.feature.flags.Flags import androidx.annotation.VisibleForTesting +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application @@ -28,8 +30,11 @@ import com.android.systemui.statusbar.phone.SystemUIDialog import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.launch /** * Provides a {@link com.android.systemui.statusbar.phone.SystemUIDialog} to be shown on the inner @@ -46,6 +51,7 @@ internal constructor( private val rearDisplayStateInteractor: RearDisplayStateInteractor, private val rearDisplayInnerDialogDelegateFactory: RearDisplayInnerDialogDelegate.Factory, @Application private val scope: CoroutineScope, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, ) : CoreStartable, AutoCloseable { companion object { @@ -53,6 +59,16 @@ internal constructor( } @VisibleForTesting var stateChangeListener: Job? = null + private val keyguardVisible = MutableStateFlow(false) + private val keyguardVisibleFlow = keyguardVisible.asStateFlow() + + @VisibleForTesting + val keyguardCallback = + object : KeyguardUpdateMonitorCallback() { + override fun onKeyguardVisibilityChanged(visible: Boolean) { + keyguardVisible.value = visible + } + } override fun close() { stateChangeListener?.cancel() @@ -62,28 +78,39 @@ internal constructor( if (Flags.deviceStateRdmV2()) { var dialog: SystemUIDialog? = null + keyguardUpdateMonitor.registerCallback(keyguardCallback) + stateChangeListener = - rearDisplayStateInteractor.state - .map { - when (it) { - is RearDisplayStateInteractor.State.Enabled -> { - val rearDisplayContext = - context.createDisplayContext(it.innerDisplay) - val delegate = - rearDisplayInnerDialogDelegateFactory.create( - rearDisplayContext, - deviceStateManager::cancelStateRequest, - ) - dialog = delegate.createDialog().apply { show() } - } + scope.launch { + combine(rearDisplayStateInteractor.state, keyguardVisibleFlow) { + rearDisplayState, + keyguardVisible -> + Pair(rearDisplayState, keyguardVisible) + } + .collectLatest { (rearDisplayState, keyguardVisible) -> + when (rearDisplayState) { + is RearDisplayStateInteractor.State.Enabled -> { + if (!keyguardVisible) { + val rearDisplayContext = + context.createDisplayContext( + rearDisplayState.innerDisplay + ) + val delegate = + rearDisplayInnerDialogDelegateFactory.create( + rearDisplayContext, + deviceStateManager::cancelStateRequest, + ) + dialog = delegate.createDialog().apply { show() } + } + } - is RearDisplayStateInteractor.State.Disabled -> { - dialog?.dismiss() - dialog = null + is RearDisplayStateInteractor.State.Disabled -> { + dialog?.dismiss() + dialog = null + } } } - } - .launchIn(scope) + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java index 4be35f147c2f..5b9717535ab5 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java @@ -78,6 +78,7 @@ import android.view.inputmethod.InputMethodManager; import androidx.annotation.NonNull; +import com.android.app.displaylib.PerDisplayRepository; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.internal.app.IVoiceInteractionSessionListener; @@ -89,6 +90,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.contextualeducation.GestureType; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.display.data.repository.DisplayRepository; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardWmStateRefactor; @@ -109,6 +111,7 @@ import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.domain.interactor.ShadeInteractor; +import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround; import com.android.systemui.shared.recents.ILauncherProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.QuickStepContract; @@ -123,8 +126,6 @@ import com.android.wm.shell.back.BackAnimation; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.sysui.ShellInterface; -import dagger.Lazy; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -136,6 +137,8 @@ import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Provider; +import dagger.Lazy; + /** * Class to send information from SysUI to Launcher with a binder. */ @@ -156,7 +159,9 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis private final Executor mMainExecutor; private final ShellInterface mShellInterface; private final Lazy<ShadeViewController> mShadeViewControllerLazy; - private SysUiState mSysUiState; + private final PerDisplayRepository<SysUiState> mPerDisplaySysUiStateRepository; + private final DisplayRepository mDisplayRepository; + private SysUiState mDefaultDisplaySysUIState; private final Handler mHandler; private final Lazy<NavigationBarController> mNavBarControllerLazy; private final ScreenPinningRequest mScreenPinningRequest; @@ -586,9 +591,12 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis // Force-update the systemui state flags updateSystemUiStateFlags(); - // TODO b/398011576 - send the state for all displays. - notifySystemUiStateFlags(mSysUiState.getFlags(), Display.DEFAULT_DISPLAY); - + if (ShadeWindowGoesAround.isEnabled()) { + notifySysUiStateFlagsForAllDisplays(); + } else { + notifySystemUiStateFlags(mDefaultDisplaySysUIState.getFlags(), + Display.DEFAULT_DISPLAY); + } notifyConnectionChanged(); } @@ -614,6 +622,18 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis } }; + /** Propagates the flags for all displays to be notified to Launcher. */ + @VisibleForTesting + public void notifySysUiStateFlagsForAllDisplays() { + var displays = mDisplayRepository.getDisplayIds().getValue(); + for (int displayId : displays) { + var state = mPerDisplaySysUiStateRepository.get(displayId); + if (state != null) { + notifySystemUiStateFlags(state.getFlags(), displayId); + } + } + } + private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged; // This is the death handler for the binder from the launcher service @@ -671,7 +691,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis ScreenPinningRequest screenPinningRequest, NavigationModeController navModeController, NotificationShadeWindowController statusBarWinController, - SysUiState sysUiState, + PerDisplayRepository<SysUiState> perDisplaySysUiStateRepository, Provider<SceneInteractor> sceneInteractor, Provider<ShadeInteractor> shadeInteractor, UserTracker userTracker, @@ -686,7 +706,8 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder, BroadcastDispatcher broadcastDispatcher, Optional<BackAnimation> backAnimation, - ProcessWrapper processWrapper + ProcessWrapper processWrapper, + DisplayRepository displayRepository ) { // b/241601880: This component should only be running for primary users or // secondaryUsers when visibleBackgroundUsers are supported. @@ -718,10 +739,10 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis com.android.internal.R.string.config_recentsComponentName)); mQuickStepIntent = new Intent(ACTION_QUICKSTEP) .setPackage(mRecentsComponentName.getPackageName()); - // TODO b/398011576 - Here we're still only handling the default display state. We should - // have a callback for any sysuiState change. - mSysUiState = sysUiState; - mSysUiState.addCallback(mSysUiStateCallback); + mPerDisplaySysUiStateRepository = perDisplaySysUiStateRepository; + mDisplayRepository = displayRepository; + mDefaultDisplaySysUIState = perDisplaySysUiStateRepository.get(Display.DEFAULT_DISPLAY); + mDefaultDisplaySysUIState.addCallback(mSysUiStateCallback); mUiEventLogger = uiEventLogger; mDisplayTracker = displayTracker; mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder; @@ -770,7 +791,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis if (mLauncherProxy != null) { try { if (DesktopModeStatus.canEnterDesktopMode(mContext) - && (sysUiState.getFlags() + && (mDefaultDisplaySysUIState.getFlags() & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0) { return; } @@ -795,7 +816,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis } public void onVoiceSessionWindowVisibilityChanged(boolean visible) { - mSysUiState.setFlag(SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING, visible) + mDefaultDisplaySysUIState.setFlag(SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING, visible) .commitUpdate(mContext.getDisplayId()); } @@ -804,23 +825,42 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis startConnectionToCurrentUser(); } - private void updateSystemUiStateFlags() { + private void updateSysUIStateForNavbars() { + if (ShadeWindowGoesAround.isEnabled()) { + var displays = mDisplayRepository.getDisplayIds().getValue(); + for (int displayId : displays) { + updateSysUIStateForNavbarWithDisplayId(displayId); + } + } else { + updateSysUIStateForNavbarWithDisplayId(Display.DEFAULT_DISPLAY); + } + } + + private void updateSysUIStateForNavbarWithDisplayId(int displayId) { final NavigationBar navBarFragment = - mNavBarControllerLazy.get().getDefaultNavigationBar(); + mNavBarControllerLazy.get().getNavigationBar(displayId); final NavigationBarView navBarView = - mNavBarControllerLazy.get().getNavigationBarView(mContext.getDisplayId()); + mNavBarControllerLazy.get().getNavigationBarView(displayId); if (SysUiState.DEBUG) { Log.d(TAG_OPS, "Updating sysui state flags: navBarFragment=" + navBarFragment + " navBarView=" + navBarView + " shadeViewController=" + mShadeViewControllerLazy.get()); } + final SysUiState displaySysuiState = mPerDisplaySysUiStateRepository.get(displayId); + if (displaySysuiState == null) return; + if (navBarFragment != null) { navBarFragment.updateSystemUiStateFlags(); } if (navBarView != null) { - navBarView.updateDisabledSystemUiStateFlags(mSysUiState); + navBarView.updateDisabledSystemUiStateFlags(displaySysuiState); } + } + + /** Force updates SystemUI state flags prior to sending them to Launcher. */ + public void updateSystemUiStateFlags() { + updateSysUIStateForNavbars(); mShadeViewControllerLazy.get().updateSystemUiStateFlags(); if (mStatusBarWinController != null) { mStatusBarWinController.notifyStateChangedCallbacks(); @@ -845,7 +885,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean keyguardGoingAway, boolean bouncerShowing, boolean isDozing, boolean panelExpanded, boolean isDreaming, boolean communalShowing) { - mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING, + mDefaultDisplaySysUIState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING, keyguardShowing && !keyguardOccluded) .setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED, keyguardShowing && keyguardOccluded) @@ -1122,7 +1162,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis new WakefulnessLifecycle.Observer() { @Override public void onStartedWakingUp() { - mSysUiState + mDefaultDisplaySysUIState .setFlag(SYSUI_STATE_AWAKE, true) .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, true) .commitUpdate(mContext.getDisplayId()); @@ -1130,7 +1170,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis @Override public void onFinishedWakingUp() { - mSysUiState + mDefaultDisplaySysUIState .setFlag(SYSUI_STATE_AWAKE, true) .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, false) .commitUpdate(mContext.getDisplayId()); @@ -1138,7 +1178,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis @Override public void onStartedGoingToSleep() { - mSysUiState + mDefaultDisplaySysUIState .setFlag(SYSUI_STATE_AWAKE, false) .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, true) .commitUpdate(mContext.getDisplayId()); @@ -1146,7 +1186,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis @Override public void onFinishedGoingToSleep() { - mSysUiState + mDefaultDisplaySysUIState .setFlag(SYSUI_STATE_AWAKE, false) .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, false) .commitUpdate(mContext.getDisplayId()); @@ -1247,7 +1287,7 @@ public class LauncherProxyService implements CallbackController<LauncherProxyLis pw.print(" mActiveNavBarRegion="); pw.println(mActiveNavBarRegion); pw.print(" mNavBarMode="); pw.println(mNavBarMode); pw.print(" mIsPrevServiceCleanedUp="); pw.println(mIsPrevServiceCleanedUp); - mSysUiState.dump(pw, args); + mDefaultDisplaySysUIState.dump(pw, args); } public interface LauncherProxyListener { diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt index c092c2f86799..9023c62347d2 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt @@ -22,15 +22,15 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.tiles.RecordIssueTile -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingDataInteractor -import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingMapper -import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingModel -import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingUserActionInteractor -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel +import com.android.systemui.qs.tiles.impl.irecording.domain.interactor.IssueRecordingDataInteractor +import com.android.systemui.qs.tiles.impl.irecording.domain.interactor.IssueRecordingUserActionInteractor +import com.android.systemui.qs.tiles.impl.irecording.ui.mapper.IssueRecordingMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module @@ -59,7 +59,7 @@ interface RecordIssueModule { uiConfig = QSTileUIConfig.Resource( iconRes = R.drawable.qs_record_issue_icon_off, - labelRes = R.string.qs_record_issue_label + labelRes = R.string.qs_record_issue_label, ), instanceId = uiEventLogger.getNewInstanceId(), category = TileCategory.UTILITIES, @@ -73,7 +73,7 @@ interface RecordIssueModule { factory: QSTileViewModelFactory.Static<IssueRecordingModel>, mapper: IssueRecordingMapper, stateInteractor: IssueRecordingDataInteractor, - userActionInteractor: IssueRecordingUserActionInteractor + userActionInteractor: IssueRecordingUserActionInteractor, ): QSTileViewModel = if (Flags.qsNewTilesFuture()) factory.create( diff --git a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt index c9712fcdaa27..ba5b4ff59971 100644 --- a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt +++ b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt @@ -20,15 +20,15 @@ import com.android.systemui.camera.CameraRotationModule import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileDataInteractor import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileUserActionInteractor import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel import com.android.systemui.qs.tiles.impl.rotation.ui.mapper.RotationLockTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel import com.android.systemui.res.R import dagger.Binds import dagger.Module @@ -73,7 +73,7 @@ interface RotationLockNewModule { factory: QSTileViewModelFactory.Static<RotationLockTileModel>, mapper: RotationLockTileMapper, stateInteractor: RotationLockTileDataInteractor, - userActionInteractor: RotationLockTileUserActionInteractor + userActionInteractor: RotationLockTileUserActionInteractor, ): QSTileViewModel = factory.create( TileSpec.create(ROTATION_TILE_SPEC), diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt index 9a9c576c5af6..b4cc05505f23 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt @@ -24,14 +24,14 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.qs.tiles.ScreenRecordTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory import com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor.ScreenRecordTileDataInteractor import com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor.ScreenRecordTileUserActionInteractor -import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.ScreenRecordTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.mapper.ScreenRecordTileMapper import com.android.systemui.res.R import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository @@ -86,7 +86,7 @@ interface ScreenRecordModule { factory: QSTileViewModelFactory.Static<ScreenRecordModel>, mapper: ScreenRecordTileMapper, stateInteractor: ScreenRecordTileDataInteractor, - userActionInteractor: ScreenRecordTileUserActionInteractor + userActionInteractor: ScreenRecordTileUserActionInteractor, ): QSTileViewModel = factory.create( TileSpec.create(SCREEN_RECORD_TILE_SPEC), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index 05ef1645c1d6..d2f424a46620 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -394,7 +394,7 @@ constructor( // Only drag down on sensitive views, otherwise the ExpandHelper will take this return if (NotificationBundleUi.isEnabled) view.entryAdapter?.isSensitive?.value == true - else view.entry.isSensitive.value + else view.entryLegacy.isSensitive.value } } return false @@ -569,7 +569,7 @@ constructor( if (NotificationBundleUi.isEnabled) { userId = expandView.entryAdapter?.sbn?.userId!! } else { - userId = expandView.entry.sbn.userId + userId = expandView.entryLegacy.sbn.userId } } var fullShadeNeedsBouncer = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 339f898be251..9bf3d5dfe4cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -47,7 +47,6 @@ import android.database.ExecutorContentObserver; import android.net.Uri; import android.os.Looper; import android.os.Process; -import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -78,6 +77,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction; @@ -920,7 +920,9 @@ public class NotificationLockscreenUserManagerImpl implements // notification's "when" time, or the notification entry creation time private long getEarliestNotificationTime(NotificationEntry notif) { long notifWhenWallClock = notif.getSbn().getNotification().getWhen(); - long creationTimeDelta = SystemClock.uptimeMillis() - notif.getCreationTime(); + long creationTimeDelta = UseElapsedRealtimeForCreationTime.getCurrentTime() + - notif.getCreationTime(); + long creationTimeWallClock = System.currentTimeMillis() - creationTimeDelta; return Math.min(notifWhenWallClock, creationTimeWallClock); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 041ed6504634..485d5b2ab555 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -169,7 +169,7 @@ public class NotificationRemoteInputManager implements CoreStartable { if (NotificationBundleUi.isEnabled()) { releaseNotificationIfKeptForRemoteInputHistory(row.getEntryAdapter()); } else { - releaseNotificationIfKeptForRemoteInputHistory(row.getEntry()); + releaseNotificationIfKeptForRemoteInputHistory(row.getEntryLegacy()); } } return started; @@ -189,8 +189,8 @@ public class NotificationRemoteInputManager implements CoreStartable { statusBarNotification = row.getEntryAdapter().getSbn(); } } else { - if (row.getEntry() != null) { - statusBarNotification = row.getEntry().getSbn(); + if (row.getEntryLegacy() != null) { + statusBarNotification = row.getEntryLegacy().getSbn(); } } if (statusBarNotification == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index f88c618a9acc..c2a87cddee55 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -675,7 +675,7 @@ public class NotificationShelf extends ActivatableNotificationView { } StatusBarIconView icon = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getIcons().getShelfIcon() - : row.getEntry().getIcons().getShelfIcon(); + : row.getEntryLegacy().getIcons().getShelfIcon(); float shelfIconPosition = getTranslationY() + icon.getTop() + icon.getTranslationY(); if (shelfIconPosition < maxTop && !mAmbientState.isFullyHidden()) { int top = (int) (maxTop - shelfIconPosition); @@ -689,7 +689,7 @@ public class NotificationShelf extends ActivatableNotificationView { private void updateContinuousClipping(final ExpandableNotificationRow row) { StatusBarIconView icon = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getIcons().getShelfIcon() - : row.getEntry().getIcons().getShelfIcon(); + : row.getEntryLegacy().getIcons().getShelfIcon(); boolean needsContinuousClipping = ViewState.isAnimatingY(icon) && !mAmbientState.isDozing(); boolean isContinuousClipping = icon.getTag(TAG_CONTINUOUS_CLIPPING) != null; if (needsContinuousClipping && !isContinuousClipping) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS index 6cebcd98a0ba..6d3c12d139db 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS @@ -18,10 +18,10 @@ per-file *Keyguard* = file:../keyguard/OWNERS per-file *Notification* = file:notification/OWNERS # Files that control blur effects on shade per-file *NotificationShadeDepth* = set noparent -per-file *NotificationShadeDepth* = shanh@google.com, rahulbanerjee@google.com +per-file *NotificationShadeDepth* = shanh@google.com, rahulbanerjee@google.com, tracyzhou@google.com per-file *NotificationShadeDepth* = file:../keyguard/OWNERS per-file *Blur* = set noparent -per-file *Blur* = shanh@google.com, rahulbanerjee@google.com +per-file *Blur* = shanh@google.com, rahulbanerjee@google.com, tracyzhou@google.com # Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*) per-file *Mode* = file:notification/OWNERS per-file *SmartReply* = set noparent diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt index 7e7031200988..922afc7825c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt @@ -17,10 +17,13 @@ package com.android.systemui.statusbar.chips.call.ui.viewmodel import android.app.PendingIntent +import android.content.ComponentName import android.content.Context import android.view.View import com.android.internal.jank.Cuj import com.android.systemui.animation.ActivityTransitionAnimator +import com.android.systemui.animation.ComposableControllerFactory +import com.android.systemui.animation.DelegateTransitionAnimatorController import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton @@ -48,7 +51,10 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.stateIn /** View model for the ongoing phone call chip shown in the status bar. */ @@ -63,14 +69,63 @@ constructor( private val activityStarter: ActivityStarter, @StatusBarChipsLog private val logger: LogBuffer, ) : OngoingActivityChipViewModel { + /** The transition cookie used to register and unregister launch and return animations. */ + private val cookie = + ActivityTransitionAnimator.TransitionCookie("${CallChipViewModel::class.java}") + + /** + * Used internally to determine when a launch or return animation is in progress, as these + * require special handling. + */ + private val transitionState: MutableStateFlow<TransitionState> = + MutableStateFlow(TransitionState.NoTransition) + + // Since we're combining the chip state and the transition state flows, getting the old value by + // using [pairwise()] would confuse things. This is because if the calculation is triggered by + // a change in transition state, the chip state will still show the previous and current values, + // making it difficult to figure out what actually changed. Instead we cache the old value here, + // so that at each update we can keep track of what actually changed. + private var latestState: OngoingCallModel = OngoingCallModel.NoCall + private var latestTransitionState: TransitionState = TransitionState.NoTransition + private val chipWithReturnAnimation: StateFlow<OngoingActivityChipModel> = if (StatusBarChipsReturnAnimations.isEnabled) { - interactor.ongoingCallState - .map { state -> - when (state) { - is OngoingCallModel.NoCall -> OngoingActivityChipModel.Inactive() + combine(interactor.ongoingCallState, transitionState) { newState, newTransitionState -> + val oldState = latestState + latestState = newState + val oldTransitionState = latestTransitionState + latestTransitionState = newTransitionState + + logger.log( + TAG, + LogLevel.DEBUG, + {}, + { + "Call chip state updated: oldState=$oldState newState=$newState " + + "oldTransitionState=$oldTransitionState " + + "newTransitionState=$newTransitionState" + }, + ) + + when (newState) { + is OngoingCallModel.NoCall -> + OngoingActivityChipModel.Inactive( + transitionManager = getTransitionManager(newState) + ) + is OngoingCallModel.InCall -> - prepareChip(state, systemClock, isHidden = state.isAppVisible) + prepareChip( + newState, + systemClock, + isHidden = + shouldChipBeHidden( + oldState = oldState, + newState = newState, + oldTransitionState = oldTransitionState, + newTransitionState = newTransitionState, + ), + transitionState = newTransitionState, + ) } } .stateIn( @@ -112,11 +167,18 @@ constructor( chipLegacy } + /** + * The controller factory that the call chip uses to register and unregister its transition + * animations. + */ + private var transitionControllerFactory: ComposableControllerFactory? = null + /** Builds an [OngoingActivityChipModel.Active] from all the relevant information. */ private fun prepareChip( state: OngoingCallModel.InCall, systemClock: SystemClock, isHidden: Boolean, + transitionState: TransitionState = TransitionState.NoTransition, ): OngoingActivityChipModel.Active { val key = state.notificationKey val contentDescription = getContentDescription(state.appName) @@ -149,6 +211,7 @@ constructor( onClickListenerLegacy = getOnClickListener(state.intent), clickBehavior = getClickBehavior(state.intent), isHidden = isHidden, + transitionManager = getTransitionManager(state, transitionState), ) } else { val startTimeInElapsedRealtime = @@ -161,6 +224,7 @@ constructor( onClickListenerLegacy = getOnClickListener(state.intent), clickBehavior = getClickBehavior(state.intent), isHidden = isHidden, + transitionManager = getTransitionManager(state, transitionState), ) } } @@ -191,9 +255,21 @@ constructor( onClick = { expandable -> StatusBarChipsModernization.unsafeAssertInNewMode() val animationController = - expandable.activityTransitionController( - Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP - ) + if ( + !StatusBarChipsReturnAnimations.isEnabled || + transitionControllerFactory == null + ) { + expandable.activityTransitionController( + Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP + ) + } else { + // When return animations are enabled, we use a long-lived registration + // with controllers created on-demand by the animation library instead + // of explicitly creating one at the time of the click. By not passing + // a controller here, we let the framework do its work. Otherwise, the + // explicit controller would take precedence and override the other one. + null + } activityStarter.postStartActivityDismissingKeyguard(intent, animationController) } ) @@ -210,6 +286,124 @@ constructor( ) } + private fun getTransitionManager( + state: OngoingCallModel, + transitionState: TransitionState = TransitionState.NoTransition, + ): OngoingActivityChipModel.TransitionManager? { + if (!StatusBarChipsReturnAnimations.isEnabled) return null + return if (state is OngoingCallModel.NoCall) { + OngoingActivityChipModel.TransitionManager( + unregisterTransition = { activityStarter.unregisterTransition(cookie) } + ) + } else { + val component = (state as OngoingCallModel.InCall).intent?.intent?.component + if (component != null) { + val factory = getTransitionControllerFactory(component) + OngoingActivityChipModel.TransitionManager( + factory, + registerTransition = { + activityStarter.registerTransition(cookie, factory, scope) + }, + // Make the chip invisible at the beginning of the return transition to avoid + // it flickering. + hideChipForTransition = transitionState is TransitionState.ReturnRequested, + ) + } else { + // Without a component we can't instantiate a controller factory, and without a + // factory registering an animation is impossible. In this case, the transition + // manager is empty and inert. + OngoingActivityChipModel.TransitionManager() + } + } + } + + private fun getTransitionControllerFactory( + component: ComponentName + ): ComposableControllerFactory { + var factory = transitionControllerFactory + if (factory?.component == component) return factory + + factory = + object : + ComposableControllerFactory( + cookie, + component, + launchCujType = Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP, + ) { + override suspend fun createController( + forLaunch: Boolean + ): ActivityTransitionAnimator.Controller { + transitionState.value = + if (forLaunch) { + TransitionState.LaunchRequested + } else { + TransitionState.ReturnRequested + } + + val controller = + expandable + .mapNotNull { + it?.activityTransitionController( + launchCujType, + cookie, + component, + returnCujType, + isEphemeral = false, + ) + } + .first() + + return object : DelegateTransitionAnimatorController(controller) { + override val isLaunching: Boolean + get() = forLaunch + + override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) { + delegate.onTransitionAnimationStart(isExpandingFullyAbove) + transitionState.value = + if (isLaunching) { + TransitionState.Launching + } else { + TransitionState.Returning + } + } + + override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) { + delegate.onTransitionAnimationEnd(isExpandingFullyAbove) + transitionState.value = TransitionState.NoTransition + } + + override fun onTransitionAnimationCancelled( + newKeyguardOccludedState: Boolean? + ) { + delegate.onTransitionAnimationCancelled(newKeyguardOccludedState) + transitionState.value = TransitionState.NoTransition + } + } + } + } + + transitionControllerFactory = factory + return factory + } + + /** Define the current state of this chip's transition animation. */ + private sealed interface TransitionState { + /** Idle. */ + data object NoTransition : TransitionState + + /** Launch animation has been requested but hasn't started yet. */ + data object LaunchRequested : TransitionState + + /** Launch animation in progress. */ + data object Launching : TransitionState + + /** Return animation has been requested but hasn't started yet. */ + data object ReturnRequested : TransitionState + + /** Return animation in progress. */ + data object Returning : TransitionState + } + companion object { private val phoneIcon = Icon.Resource( @@ -217,5 +411,42 @@ constructor( ContentDescription.Resource(R.string.ongoing_call_content_description), ) private val TAG = "CallVM".pad() + + /** Determines whether or not an active call chip should be hidden. */ + private fun shouldChipBeHidden( + oldState: OngoingCallModel, + newState: OngoingCallModel.InCall, + oldTransitionState: TransitionState, + newTransitionState: TransitionState, + ): Boolean { + // The app is in the background and no transitions are ongoing (during transitions, + // [isAppVisible] must always be true). Show the chip. + if (!newState.isAppVisible) return false + + // The call has just started and is visible. Hide the chip. + if (oldState is OngoingCallModel.NoCall) return true + + // The state went from the app not being visible to visible. This happens when the chip + // is tapped and a launch animation is about to start. Keep the chip showing. + if (!(oldState as OngoingCallModel.InCall).isAppVisible) return false + + // The app was and remains visible, but the transition state has changed. A launch or + // return animation has been requested or is ongoing. Keep the chip showing. + if ( + newTransitionState is TransitionState.LaunchRequested || + newTransitionState is TransitionState.Launching || + newTransitionState is TransitionState.ReturnRequested || + newTransitionState is TransitionState.Returning + ) { + return false + } + + // The app was and remains visible, so we generally want to hide the chip. The only + // exception is if a return transition has just ended. In this case, the transition + // state changes shortly before the app visibility does. If we hide the chip between + // these two updates, this results in a flicker. We bridge the gap by keeping the chip + // showing. + return oldTransitionState != TransitionState.Returning + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt index 4edb23dc9f0e..74b3f302cdc8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource @@ -42,6 +43,7 @@ import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.load import com.android.systemui.res.R import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.chips.StatusBarChipsReturnAnimations import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.core.StatusBarConnectedDisplays @@ -83,13 +85,25 @@ fun OngoingActivityChip( shape = RoundedCornerShape(dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius)), modifier = - modifier.height(dimensionResource(R.dimen.ongoing_appops_chip_height)).semantics { - if (contentDescription != null) { - this.contentDescription = contentDescription + modifier + .height(dimensionResource(R.dimen.ongoing_appops_chip_height)) + .semantics { + if (contentDescription != null) { + this.contentDescription = contentDescription + } } - }, + .graphicsLayer( + alpha = + if (model.transitionManager?.hideChipForTransition == true) { + 0f + } else { + 1f + } + ), borderStroke = borderStroke, onClick = onClick, + useModifierBasedImplementation = StatusBarChipsReturnAnimations.isEnabled, + transitionControllerFactory = model.transitionManager?.controllerFactory, ) { ChipBody(model, iconViewStore, isClickable = onClick != null) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt index 407849b9fae0..700e6d93c628 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt @@ -21,12 +21,14 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.key import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.res.R +import com.android.systemui.statusbar.chips.StatusBarChipsReturnAnimations import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder @@ -36,6 +38,18 @@ fun OngoingActivityChips( iconViewStore: NotificationIconContainerViewBinder.IconViewStore?, modifier: Modifier = Modifier, ) { + if (StatusBarChipsReturnAnimations.isEnabled) { + SideEffect { + // Active chips must always be capable of animating to/from activities, even when they + // are hidden. Therefore we always register their transitions. + for (chip in chips.active) chip.transitionManager?.registerTransition?.invoke() + // Inactive chips and chips in the overflow are never shown, so they must not have any + // registered transition. + for (chip in chips.overflow) chip.transitionManager?.unregisterTransition?.invoke() + for (chip in chips.inactive) chip.transitionManager?.unregisterTransition?.invoke() + } + } + val shownChips = chips.active.filter { !it.isHidden } if (shownChips.isNotEmpty()) { Row( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt index d37a46e58882..364e6656ee9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt @@ -20,6 +20,7 @@ import android.annotation.CurrentTimeMillisLong import android.annotation.ElapsedRealtimeLong import android.os.SystemClock import android.view.View +import com.android.systemui.animation.ComposableControllerFactory import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon @@ -33,6 +34,9 @@ sealed class OngoingActivityChipModel { /** Condensed name representing the model, used for logs. */ abstract val logName: String + /** Object used to manage the behavior of this chip during activity launch and returns. */ + abstract val transitionManager: TransitionManager? + /** * This chip shouldn't be shown. * @@ -40,7 +44,10 @@ sealed class OngoingActivityChipModel { * animated, and false if that transition should *not* be animated (i.e. the chip view should * immediately disappear). */ - data class Inactive(val shouldAnimate: Boolean = true) : OngoingActivityChipModel() { + data class Inactive( + val shouldAnimate: Boolean = true, + override val transitionManager: TransitionManager? = null, + ) : OngoingActivityChipModel() { override val logName = "Inactive(anim=$shouldAnimate)" } @@ -61,6 +68,7 @@ sealed class OngoingActivityChipModel { open val onClickListenerLegacy: View.OnClickListener?, /** Data class that determines how clicks on the chip should be handled. */ open val clickBehavior: ClickBehavior, + override val transitionManager: TransitionManager?, /** * Whether this chip should be hidden. This can be the case depending on system states (like * which apps are in the foreground and whether there is an ongoing transition. @@ -77,6 +85,7 @@ sealed class OngoingActivityChipModel { override val colors: ColorsModel, override val onClickListenerLegacy: View.OnClickListener?, override val clickBehavior: ClickBehavior, + override val transitionManager: TransitionManager? = null, override val isHidden: Boolean = false, override val shouldAnimate: Boolean = true, ) : @@ -86,6 +95,7 @@ sealed class OngoingActivityChipModel { colors, onClickListenerLegacy, clickBehavior, + transitionManager, isHidden, shouldAnimate, ) { @@ -122,6 +132,7 @@ sealed class OngoingActivityChipModel { val isEventInFuture: Boolean = false, override val onClickListenerLegacy: View.OnClickListener?, override val clickBehavior: ClickBehavior, + override val transitionManager: TransitionManager? = null, override val isHidden: Boolean = false, override val shouldAnimate: Boolean = true, ) : @@ -131,6 +142,7 @@ sealed class OngoingActivityChipModel { colors, onClickListenerLegacy, clickBehavior, + transitionManager, isHidden, shouldAnimate, ) { @@ -157,6 +169,7 @@ sealed class OngoingActivityChipModel { @CurrentTimeMillisLong val time: Long, override val onClickListenerLegacy: View.OnClickListener?, override val clickBehavior: ClickBehavior, + override val transitionManager: TransitionManager? = null, override val isHidden: Boolean = false, override val shouldAnimate: Boolean = true, ) : @@ -166,6 +179,7 @@ sealed class OngoingActivityChipModel { colors, onClickListenerLegacy, clickBehavior, + transitionManager, isHidden, shouldAnimate, ) { @@ -185,6 +199,7 @@ sealed class OngoingActivityChipModel { override val colors: ColorsModel, /** The number of seconds until an event is started. */ val secondsUntilStarted: Long, + override val transitionManager: TransitionManager? = null, override val isHidden: Boolean = false, override val shouldAnimate: Boolean = true, ) : @@ -194,6 +209,7 @@ sealed class OngoingActivityChipModel { colors, onClickListenerLegacy = null, clickBehavior = ClickBehavior.None, + transitionManager, isHidden, shouldAnimate, ) { @@ -209,6 +225,7 @@ sealed class OngoingActivityChipModel { val text: String, override val onClickListenerLegacy: View.OnClickListener? = null, override val clickBehavior: ClickBehavior, + override val transitionManager: TransitionManager? = null, override val isHidden: Boolean = false, override val shouldAnimate: Boolean = true, ) : @@ -218,6 +235,7 @@ sealed class OngoingActivityChipModel { colors, onClickListenerLegacy, clickBehavior, + transitionManager, isHidden, shouldAnimate, ) { @@ -271,4 +289,23 @@ sealed class OngoingActivityChipModel { /** Clicking the chip will show the heads up notification associated with the chip. */ data class ShowHeadsUpNotification(val onClick: () -> Unit) : ClickBehavior } + + /** Defines the behavior of the chip with respect to activity launch and return transitions. */ + data class TransitionManager( + /** The factory used to create the controllers that animate the chip. */ + val controllerFactory: ComposableControllerFactory? = null, + /** + * Used to create a registration for this chip using [controllerFactory]. Must be + * idempotent. + */ + val registerTransition: () -> Unit = {}, + /** Used to remove the existing registration for this chip, if any. */ + val unregisterTransition: () -> Unit = {}, + /** + * Whether the chip should be made invisible (0 opacity) while still being composed. This is + * necessary to avoid flickers at the beginning of return transitions, when the chip must + * not be visible but must be composed in order for the animation to start. + */ + val hideChipForTransition: Boolean = false, + ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt index 48f0245fd5db..4cf456d69b7b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt @@ -32,25 +32,25 @@ import com.android.systemui.qs.tiles.HotspotTile import com.android.systemui.qs.tiles.InternetTile import com.android.systemui.qs.tiles.InternetTileNewImpl import com.android.systemui.qs.tiles.NfcTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel -import com.android.systemui.qs.tiles.impl.airplane.domain.AirplaneModeMapper import com.android.systemui.qs.tiles.impl.airplane.domain.interactor.AirplaneModeTileDataInteractor import com.android.systemui.qs.tiles.impl.airplane.domain.interactor.AirplaneModeTileUserActionInteractor import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel -import com.android.systemui.qs.tiles.impl.internet.domain.InternetTileMapper +import com.android.systemui.qs.tiles.impl.airplane.ui.mapper.AirplaneModeTileMapper import com.android.systemui.qs.tiles.impl.internet.domain.interactor.InternetTileDataInteractor import com.android.systemui.qs.tiles.impl.internet.domain.interactor.InternetTileUserActionInteractor import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel -import com.android.systemui.qs.tiles.impl.saver.domain.DataSaverTileMapper +import com.android.systemui.qs.tiles.impl.internet.ui.mapper.InternetTileMapper import com.android.systemui.qs.tiles.impl.saver.domain.interactor.DataSaverTileDataInteractor import com.android.systemui.qs.tiles.impl.saver.domain.interactor.DataSaverTileUserActionInteractor import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.impl.saver.ui.mapper.DataSaverTileMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module @@ -161,10 +161,10 @@ interface ConnectivityModule { @StringKey(AIRPLANE_MODE_TILE_SPEC) fun provideAirplaneModeTileViewModel( factory: QSTileViewModelFactory.Static<AirplaneModeTileModel>, - mapper: AirplaneModeMapper, + mapper: AirplaneModeTileMapper, stateInteractor: AirplaneModeTileDataInteractor, userActionInteractor: AirplaneModeTileUserActionInteractor, - internetDetailsViewModelFactory: InternetDetailsViewModel.Factory + internetDetailsViewModelFactory: InternetDetailsViewModel.Factory, ): QSTileViewModel = factory.create( TileSpec.create(AIRPLANE_MODE_TILE_SPEC), @@ -197,7 +197,7 @@ interface ConnectivityModule { factory: QSTileViewModelFactory.Static<DataSaverTileModel>, mapper: DataSaverTileMapper, stateInteractor: DataSaverTileDataInteractor, - userActionInteractor: DataSaverTileUserActionInteractor + userActionInteractor: DataSaverTileUserActionInteractor, ): QSTileViewModel = factory.create( TileSpec.create(DATA_SAVER_TILE_SPEC), @@ -230,7 +230,7 @@ interface ConnectivityModule { mapper: InternetTileMapper, stateInteractor: InternetTileDataInteractor, userActionInteractor: InternetTileUserActionInteractor, - internetDetailsViewModelFactory: InternetDetailsViewModel.Factory + internetDetailsViewModelFactory: InternetDetailsViewModel.Factory, ): QSTileViewModel = factory.create( TileSpec.create(INTERNET_TILE_SPEC), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt index 3168a22c56ad..cb1002a83179 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt @@ -17,14 +17,14 @@ package com.android.systemui.statusbar.data.repository import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR +import com.android.app.displaylib.PerDisplayInstanceProvider +import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl +import com.android.app.displaylib.PerDisplayRepository +import com.android.app.displaylib.SingleInstanceRepositoryImpl import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.common.ui.ConfigurationStateImpl import com.android.systemui.dagger.SysUISingleton import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository -import com.android.systemui.display.data.repository.PerDisplayInstanceProvider -import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl -import com.android.systemui.display.data.repository.PerDisplayRepository -import com.android.systemui.display.data.repository.SingleInstanceRepositoryImpl import com.android.systemui.statusbar.core.StatusBarConnectedDisplays import dagger.Lazy import dagger.Module @@ -39,7 +39,6 @@ constructor( private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore, private val factory: ConfigurationStateImpl.Factory, ) : PerDisplayInstanceProvider<ConfigurationState> { - override fun createInstance(displayId: Int): ConfigurationState? { val displayWindowProperties = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java index 8be9e410f8f6..3bb1ff161b6f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java @@ -23,6 +23,7 @@ import android.view.View; import com.android.systemui.DejankUtils; import com.android.systemui.power.domain.interactor.PowerInteractor; +import com.android.systemui.statusbar.notification.collection.EntryAdapter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; @@ -44,13 +45,20 @@ public final class NotificationClicker implements View.OnClickListener { private final Optional<Bubbles> mBubblesOptional; private final NotificationActivityStarter mNotificationActivityStarter; - private ExpandableNotificationRow.OnDragSuccessListener mOnDragSuccessListener = - new ExpandableNotificationRow.OnDragSuccessListener() { - @Override - public void onDragSuccess(NotificationEntry entry) { - mNotificationActivityStarter.onDragSuccess(entry); - } - }; + private ExpandableNotificationRow.OnDragSuccessListener mOnDragSuccessListener + = new ExpandableNotificationRow.OnDragSuccessListener() { + @Override + public void onDragSuccess(NotificationEntry entry) { + NotificationBundleUi.assertInLegacyMode(); + mNotificationActivityStarter.onDragSuccess(entry); + } + + @Override + public void onDragSuccess(EntryAdapter entryAdapter) { + NotificationBundleUi.isUnexpectedlyInLegacyMode(); + entryAdapter.onDragSuccess(); + } + }; private NotificationClicker( NotificationClickerLogger logger, @@ -105,7 +113,7 @@ public final class NotificationClicker implements View.OnClickListener { mBubblesOptional.get().collapseStack(); } } else { - if (!row.getEntry().isBubble() && mBubblesOptional.isPresent()) { + if (!row.getEntryLegacy().isBubble() && mBubblesOptional.isPresent()) { mBubblesOptional.get().collapseStack(); } } @@ -130,7 +138,7 @@ public final class NotificationClicker implements View.OnClickListener { } else { row.setBubbleClickListener(v -> mNotificationActivityStarter.onNotificationBubbleIconClicked( - row.getEntry())); + row.getEntryLegacy())); } row.setOnClickListener(this); row.setOnDragSuccessListener(mOnDragSuccessListener); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt index 874a059d2323..8163128f762a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt @@ -74,7 +74,6 @@ class NotificationTransitionAnimatorController( const val ANIMATION_DURATION_TOP_ROUNDING = 100L } - private val notificationEntry = notification.entry private val notificationKey = notification.key override val isLaunching: Boolean = true @@ -160,7 +159,7 @@ class NotificationTransitionAnimatorController( private val headsUpNotificationRow: ExpandableNotificationRow? get() { val pipelineParent = if (NotificationBundleUi.isEnabled) - notification.entryAdapter?.parent else notificationEntry.parent + notification.entryAdapter?.parent else notification.entryLegacy.parent val summaryEntry = (pipelineParent as? GroupEntry)?.summary return when { headsUpManager.isHeadsUpEntry(notificationKey) -> notification diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt index b1a26af336d8..e743d87a784c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt @@ -22,6 +22,7 @@ import android.os.Build import android.service.notification.StatusBarNotification import android.util.Log import com.android.systemui.statusbar.notification.icon.IconPack +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import kotlinx.coroutines.flow.StateFlow @@ -113,6 +114,10 @@ class BundleEntryAdapter(val entry: BundleEntry) : EntryAdapter { return false } + override fun getPeopleNotificationType(): Int { + return TYPE_NON_PERSON + } + override fun isPromotedOngoing(): Boolean { return false } @@ -121,6 +126,11 @@ class BundleEntryAdapter(val entry: BundleEntry) : EntryAdapter { return false } + override fun onDragSuccess() { + // do nothing. these should not be draggable + Log.wtf(TAG, "onDragSuccess() called") + } + override fun onNotificationBubbleIconClicked() { // do nothing. these cannot be a bubble Log.wtf(TAG, "onNotificationBubbleIconClicked() called") @@ -130,6 +140,16 @@ class BundleEntryAdapter(val entry: BundleEntry) : EntryAdapter { // do nothing. these have no actions Log.wtf(TAG, "onNotificationActionClicked() called") } + + override fun getDismissState(): NotificationEntry.DismissState { + // TODO(b/394483200): setDismissState is only called in NotifCollection so it does not + // work on bundles yet + return NotificationEntry.DismissState.NOT_DISMISSED + } + + override fun onEntryClicked(row: ExpandableNotificationRow) { + // TODO(b/396446620): should anything happen when you click on a bundle? + } } private const val TAG = "BundleEntryAdapter" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java index 4299825bd5e3..f39bd0324995 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java @@ -23,6 +23,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.systemui.statusbar.notification.icon.IconPack; +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import kotlinx.coroutines.flow.StateFlow; @@ -132,6 +133,8 @@ public interface EntryAdapter { boolean isAmbient(); + @PeopleNotificationIdentifier.Companion.PeopleNotificationType int getPeopleNotificationType(); + /** * Returns whether this row represents promoted ongoing notification. */ @@ -141,6 +144,8 @@ public interface EntryAdapter { return false; } + void onDragSuccess(); + /** * Process a click on a notification bubble icon */ @@ -150,5 +155,9 @@ public interface EntryAdapter { * Processes a click on a notification action */ void onNotificationActionClicked(); + + NotificationEntry.DismissState getDismissState(); + + void onEntryClicked(ExpandableNotificationRow row); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java index caa7abb1aa7a..8f7f61f6be65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java @@ -34,7 +34,7 @@ public abstract class ListEntry extends PipelineEntry { } /** - * The SystemClock.uptimeMillis() when this object was created. In general, this means the + * The SystemClock.elapsedRealtime() when this object was created. In general, this means the * moment when NotificationManager notifies our listener about the existence of this entry. * * This value will not change if the notification is updated, although it will change if the @@ -65,13 +65,4 @@ public abstract class ListEntry extends PipelineEntry { @Nullable public PipelineEntry getPreviousParent() { return mPreviousAttachState.getParent(); } - - /** - * Stores the current attach state into {@link #getPreviousAttachState()}} and then starts a - * fresh attach state (all entries will be null/default-initialized). - */ - void beginNewAttachState() { - mPreviousAttachState.clone(mAttachState); - mAttachState.reset(); - } } 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 9795edf3313c..b7fe39e9c757 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 @@ -522,7 +522,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable { } private void onNotificationsInitialized() { - mInitializedTimestamp = mClock.uptimeMillis(); + mInitializedTimestamp = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock); } private void postNotification( @@ -532,7 +532,8 @@ public class NotifCollection implements Dumpable, PipelineDumpable { if (entry == null) { // A new notification! - entry = new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + entry = new NotificationEntry(sbn, ranking, + UseElapsedRealtimeForCreationTime.getCurrentTime(mClock)); mEventQueue.add(new InitEntryEvent(entry)); mEventQueue.add(new BindEntryEvent(entry, sbn)); mNotificationSet.put(sbn.getKey(), entry); @@ -861,7 +862,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable { // messages from system server. private void crashIfNotInitializing(RuntimeException exception) { final boolean isRecentlyInitialized = mInitializedTimestamp == 0 - || mClock.uptimeMillis() - mInitializedTimestamp + || UseElapsedRealtimeForCreationTime.getCurrentTime(mClock) - mInitializedTimestamp < INITIALIZATION_FORGIVENESS_WINDOW; if (isRecentlyInitialized) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt index 1f8d365cfdad..698fed33a408 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt @@ -89,9 +89,9 @@ class NotifCollectionCache<V>( return true } - // Using uptimeMillis since it's guaranteed to be monotonic, as we don't want a + // Using elapsedRealtime since it's guaranteed to be monotonic, as we don't want a // timezone/clock change to break us - val now = systemClock.uptimeMillis() + val now = UseElapsedRealtimeForCreationTime.getCurrentTime(systemClock) // Cannot purge the same entry from two threads simultaneously synchronized(key) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index d031d831bf5a..4558017a98c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -251,7 +251,7 @@ public final class NotificationEntry extends ListEntry { /** * @param sbn the StatusBarNotification from system server * @param ranking also from system server - * @param creationTime SystemClock.uptimeMillis of when we were created + * @param creationTime SystemClock.elapsedRealtime of when we were created */ public NotificationEntry( @NonNull StatusBarNotification sbn, @@ -508,7 +508,7 @@ public final class NotificationEntry extends ListEntry { ArrayList<NotificationEntry> children = new ArrayList<>(); for (ExpandableNotificationRow child : rowChildren) { - children.add(child.getEntry()); + children.add(child.getEntryLegacy()); } return children; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt index 345b6aae9673..12cfa91d9890 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt @@ -137,6 +137,10 @@ class NotificationEntryAdapter( return entry.ranking.isAmbient } + override fun getPeopleNotificationType(): Int { + return peopleNotificationIdentifier.getPeopleNotificationType(entry) + } + override fun isPromotedOngoing(): Boolean { return entry.isPromotedOngoing } @@ -145,6 +149,10 @@ class NotificationEntryAdapter( return entry.sbn.notification.fullScreenIntent != null } + override fun onDragSuccess() { + notificationActivityStarter.onDragSuccess(entry) + } + override fun onNotificationBubbleIconClicked() { notificationActivityStarter.onNotificationBubbleIconClicked(entry) } @@ -152,4 +160,12 @@ class NotificationEntryAdapter( override fun onNotificationActionClicked() { notificationActionClickManager.onNotificationActionClicked(entry) } + + override fun getDismissState(): NotificationEntry.DismissState { + return entry.dismissState + } + + override fun onEntryClicked(row: ExpandableNotificationRow) { + notificationActivityStarter.onNotificationClicked(entry, row) + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java index 872cd68e1b21..e9c4efc4de64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java @@ -101,4 +101,13 @@ public abstract class PipelineEntry { public void setBucket(@PriorityBucket int bucket) { mBucket = bucket; } + + /** + * Stores the current attach state into {@link #getPreviousAttachState()}} and then starts a + * fresh attach state (all entries will be null/default-initialized). + */ + void beginNewAttachState() { + mPreviousAttachState.clone(mAttachState); + mAttachState.reset(); + } } 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 780e8f47a7fe..5cea82140692 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 @@ -565,6 +565,11 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable { entry.beginNewAttachState(); } + for (BundleEntry be : mIdToBundleEntry.values()) { + be.beginNewAttachState(); + // TODO(b/399736937) Clear bundle children + // BundleEntry has not representative summary so we do not need to clear it here. + } mNotifList.clear(); } @@ -573,7 +578,7 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable { List<PipelineEntry> out, List<NotifFilter> filters) { Trace.beginSection("ShadeListBuilder.filterNotifs"); - final long now = mSystemClock.uptimeMillis(); + final long now = UseElapsedRealtimeForCreationTime.getCurrentTime(mSystemClock); for (PipelineEntry entry : entries) { if (entry instanceof GroupEntry) { final GroupEntry groupEntry = (GroupEntry) entry; @@ -617,7 +622,8 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable { GroupEntry group = mGroups.get(topLevelKey); if (group == null) { - group = new GroupEntry(topLevelKey, mSystemClock.uptimeMillis()); + group = new GroupEntry(topLevelKey, + UseElapsedRealtimeForCreationTime.getCurrentTime(mSystemClock)); mGroups.put(topLevelKey, group); } if (group.getParent() == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/UseElapsedRealtimeForCreationTime.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/UseElapsedRealtimeForCreationTime.kt new file mode 100644 index 000000000000..23f90f3694a8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/UseElapsedRealtimeForCreationTime.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection + +import android.app.Flags +import com.android.systemui.util.time.SystemClock + +/** A helper class for replacing uptimeMillis with elapsedRealtime for entry creation times */ +public object UseElapsedRealtimeForCreationTime { + @JvmStatic + fun getCurrentTime(clock: SystemClock): Long { + if (Flags.notifEntryCreationTimeUseElapsedRealtime()) { + return clock.elapsedRealtime() + } + return clock.uptimeMillis() + } + + @JvmStatic + fun getCurrentTime(): Long { + if (Flags.notifEntryCreationTimeUseElapsedRealtime()) { + return android.os.SystemClock.elapsedRealtime() + } + return android.os.SystemClock.uptimeMillis() + + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java index 2eec68b26347..fb7772e26240 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java @@ -25,7 +25,7 @@ import java.util.List; * Represents a set of notification post events for a particular notification group. */ public class EventBatch { - /** SystemClock.uptimeMillis() */ + /** SystemClock.elapsedRealtime() */ final long mCreatedTimestamp; /** SBN.getGroupKey -- same for all members */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java index 96b35428b3ce..944e313d795a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; import com.android.systemui.statusbar.notification.collection.PipelineDumpable; import com.android.systemui.statusbar.notification.collection.PipelineDumper; +import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.time.SystemClock; @@ -182,11 +183,12 @@ public class GroupCoalescer implements Dumpable, PipelineDumpable { private void maybeEmitBatch(StatusBarNotification sbn) { final CoalescedEvent event = mCoalescedEvents.get(sbn.getKey()); final EventBatch batch = mBatches.get(sbn.getGroupKey()); + long now = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock); if (event != null) { mLogger.logEarlyEmit(sbn.getKey(), requireNonNull(event.getBatch()).mGroupKey); emitBatch(requireNonNull(event.getBatch())); } else if (batch != null - && mClock.uptimeMillis() - batch.mCreatedTimestamp >= mMaxGroupLingerDuration) { + && now - batch.mCreatedTimestamp >= mMaxGroupLingerDuration) { mLogger.logMaxBatchTimeout(sbn.getKey(), batch.mGroupKey); emitBatch(batch); } @@ -228,7 +230,8 @@ public class GroupCoalescer implements Dumpable, PipelineDumpable { private EventBatch getOrBuildBatch(final String groupKey) { EventBatch batch = mBatches.get(groupKey); if (batch == null) { - batch = new EventBatch(mClock.uptimeMillis(), groupKey); + batch = new EventBatch(UseElapsedRealtimeForCreationTime.getCurrentTime(mClock), + groupKey); mBatches.put(groupKey, batch); } return batch; @@ -268,7 +271,8 @@ public class GroupCoalescer implements Dumpable, PipelineDumpable { } events.sort(mEventComparator); - long batchAge = mClock.uptimeMillis() - batch.mCreatedTimestamp; + long batchAge = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock) + - batch.mCreatedTimestamp; mLogger.logEmitBatch(batch.mGroupKey, batch.mMembers.size(), batchAge); mHandler.onNotificationBatchPosted(events); @@ -298,7 +302,7 @@ public class GroupCoalescer implements Dumpable, PipelineDumpable { @Override public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { - long now = mClock.uptimeMillis(); + long now = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock); int eventCount = 0; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java index b54f21b23bba..1be415d7bf47 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java @@ -241,8 +241,7 @@ public class PreparationCoordinator implements Coordinator { isMemberOfDelayedGroup = shouldWaitForGroupToInflate(parent, now); mIsDelayedGroupCache.put(parent, isMemberOfDelayedGroup); } - - return !isInflated(entry) || isMemberOfDelayedGroup; + return !isInflated(entry) || (isMemberOfDelayedGroup != null && isMemberOfDelayedGroup); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt index a0a86710b4ba..f43767d3effb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt @@ -22,7 +22,6 @@ import com.android.internal.widget.MessagingGroup import com.android.internal.widget.MessagingMessage import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.Flags import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener @@ -147,9 +146,7 @@ internal constructor( traceSection("updateNotifOnUiModeChanged") { mPipeline?.allNotifs?.forEach { entry -> entry.row?.onUiModeChanged() - if (Flags.notificationUndoGutsOnConfigChanged()) { - mGutsManager.closeAndUndoGuts() - } + mGutsManager.closeAndUndoGuts() } } } @@ -158,16 +155,7 @@ internal constructor( colorUpdateLogger.logEvent("VCC.updateNotificationsOnDensityOrFontScaleChanged()") mPipeline?.allNotifs?.forEach { entry -> entry.onDensityOrFontScaleChanged() - if (Flags.notificationUndoGutsOnConfigChanged()) { - mGutsManager.closeAndUndoGuts() - } else { - // This property actually gets reset when the guts are re-inflated, so we're never - // actually calling onDensityOrFontScaleChanged below. - val exposedGuts = entry.areGutsExposed() - if (exposedGuts) { - mGutsManager.onDensityOrFontScaleChanged(entry) - } - } + mGutsManager.closeAndUndoGuts() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java index 27765635edcb..0466c0359710 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java @@ -501,7 +501,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { * notification and we are reordering based on the user's change. * * @param entry notification entry that can change sections even if isReorderingAllowed is false - * @param now current time SystemClock.uptimeMillis + * @param now current time SystemClock.elapsedRealtime */ public void temporarilyAllowSectionChanges(@NonNull NotificationEntry entry, long now) { final String entryKey = entry.getKey(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java index 07fa6aeb7900..03b4076ba6fb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java @@ -20,7 +20,6 @@ import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_N import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; -import android.os.SystemClock; import android.service.notification.NotificationStats; import androidx.annotation.NonNull; @@ -30,6 +29,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime; import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; @@ -85,7 +85,7 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback public void onImportanceChanged(NotificationEntry entry) { mVisualStabilityCoordinator.temporarilyAllowSectionChanges( entry, - SystemClock.uptimeMillis()); + UseElapsedRealtimeForCreationTime.getCurrentTime()); } @NonNull diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java index 776c7d5eb7f6..389bb3129c8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java @@ -41,8 +41,8 @@ public abstract class NotifFilter extends Pluggable<NotifFilter> { * this entry will not have any grouping nor sorting information. * If this filter is registered via {@link NotifPipeline#addFinalizeFilter}, * this entry will have grouping and sorting information. - * @param now A timestamp in SystemClock.uptimeMillis that represents "now" for the purposes of - * pipeline execution. This value will be the same for all pluggable calls made + * @param now A timestamp in SystemClock.elapsedRealtime that represents "now" for the purposes + * of pipeline execution. This value will be the same for all pluggable calls made * during this pipeline run, giving pluggables a stable concept of "now" to compare * various entries against. * @return True if the notif should be removed from the list diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt index cdbe0fd23a9a..8d1e61123fdd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt @@ -81,7 +81,7 @@ constructor( if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { flowOf(emptySet()) } else { - activeHeadsUpRows.map { it.map { (repo, _) -> repo }.toSet() } + activeHeadsUpRows.map { it.map { (repo, _) -> repo }.toSet() }.distinctUntilChanged() } } @@ -90,9 +90,9 @@ constructor( if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { flowOf(emptySet()) } else { - activeHeadsUpRows.map { - it.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet() - } + activeHeadsUpRows + .map { it.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet() } + .distinctUntilChanged() // TODO(b/402428276) stop sending duplicate updates instead } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt index 147a5afea306..619d48f8ba81 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt @@ -18,9 +18,9 @@ package com.android.systemui.statusbar.notification.icon.ui.viewbinder import android.view.Display import androidx.lifecycle.lifecycleScope +import com.android.app.displaylib.PerDisplayRepository import com.android.app.tracing.traceSection import com.android.systemui.common.ui.ConfigurationState -import com.android.systemui.display.data.repository.PerDisplayRepository import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.statusbar.notification.collection.NotifCollection import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index ec8fbc08de7a..5bdd769dfa03 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -19,7 +19,6 @@ import android.content.Context; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.util.ArrayMap; import android.util.ArraySet; @@ -44,6 +43,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.UpdateSource; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; @@ -112,7 +112,7 @@ public class NotificationLogger implements StateListener, CoreStartable, @Override public void run() { - mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis(); + mLastVisibilityReportUptimeMs = UseElapsedRealtimeForCreationTime.getCurrentTime(); // 1. Loop over active entries: // A. Keep list of visible notifications. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt index 2a01a14f56aa..777392df67cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt @@ -19,19 +19,26 @@ package com.android.systemui.statusbar.notification.promoted import android.app.Flags import android.app.Flags.notificationsRedesignTemplates import android.app.Notification +import android.content.Context import android.graphics.PorterDuff import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.View.GONE +import android.view.View.MeasureSpec.AT_MOST +import android.view.View.MeasureSpec.EXACTLY +import android.view.View.MeasureSpec.UNSPECIFIED +import android.view.View.MeasureSpec.makeMeasureSpec import android.view.View.VISIBLE import android.view.ViewGroup.MarginLayoutParams import android.view.ViewStub import android.widget.Chronometer import android.widget.DateTimeView +import android.widget.FrameLayout import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView +import androidx.annotation.DimenRes import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box @@ -42,7 +49,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.key import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.view.isVisible @@ -88,22 +97,12 @@ fun AODPromotedNotification( } key(content.identity) { - val sidePaddings = dimensionResource(systemuiR.dimen.notification_side_paddings) - val sidePaddingValues = PaddingValues(horizontal = sidePaddings, vertical = 0.dp) - - val borderStroke = BorderStroke(1.dp, SecondaryText.brush) - - val borderRadius = dimensionResource(systemuiR.dimen.notification_corner_radius) - val borderShape = RoundedCornerShape(borderRadius) - - Box(modifier = modifier.padding(sidePaddingValues)) { - AODPromotedNotificationView( - layoutResource = layoutResource, - content = content, - audiblyAlertedIconVisible = audiblyAlertedIconVisible, - modifier = Modifier.border(borderStroke, borderShape), - ) - } + AODPromotedNotificationView( + layoutResource = layoutResource, + content = content, + audiblyAlertedIconVisible = audiblyAlertedIconVisible, + modifier = modifier, + ) } } @@ -114,27 +113,91 @@ fun AODPromotedNotificationView( audiblyAlertedIconVisible: Boolean, modifier: Modifier = Modifier, ) { - AndroidView( - factory = { context -> - val view = - traceSection("$TAG.inflate") { - LayoutInflater.from(context).inflate(layoutResource, /* root= */ null) - } - - val updater = - traceSection("$TAG.findViews") { AODPromotedNotificationViewUpdater(view) } - - view.setTag(viewUpdaterTagId, updater) - - view - }, - update = { view -> - val updater = view.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater - - traceSection("$TAG.update") { updater.update(content, audiblyAlertedIconVisible) } - }, - modifier = modifier, - ) + val sidePaddings = dimensionResource(systemuiR.dimen.notification_side_paddings) + val sidePaddingValues = PaddingValues(horizontal = sidePaddings, vertical = 0.dp) + + val boxModifier = modifier.padding(sidePaddingValues) + + val borderStroke = BorderStroke(1.dp, SecondaryText.brush) + + val borderRadius = dimensionResource(systemuiR.dimen.notification_corner_radius) + val borderShape = RoundedCornerShape(borderRadius) + + val maxHeight = + with(LocalDensity.current) { + scaledFontHeight(systemuiR.dimen.notification_max_height_for_promoted_ongoing) + .toPx() + } + .toInt() + + val viewModifier = Modifier.border(borderStroke, borderShape) + + Box(modifier = boxModifier) { + AndroidView( + factory = { context -> + val notif = + traceSection("$TAG.inflate") { + LayoutInflater.from(context).inflate(layoutResource, /* root= */ null) + } + val updater = + traceSection("$TAG.findViews") { AODPromotedNotificationViewUpdater(notif) } + + val frame = FrameLayoutWithMaxHeight(maxHeight, context) + frame.addView(notif) + frame.setTag(viewUpdaterTagId, updater) + + frame + }, + update = { frame -> + val updater = frame.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater + + traceSection("$TAG.update") { updater.update(content, audiblyAlertedIconVisible) } + frame.maxHeight = maxHeight + }, + modifier = viewModifier, + ) + } +} + +private class FrameLayoutWithMaxHeight(maxHeight: Int, context: Context) : FrameLayout(context) { + var maxHeight = maxHeight + set(value) { + if (field != value) { + field = value + requestLayout() + } + } + + // This mirrors the logic in NotificationContentView.onMeasure. + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + if (childCount < 1) { + return + } + + val child = getChildAt(0) + val childLayoutHeight = child.layoutParams.height + val childHeightSpec = + if (childLayoutHeight >= 0) { + makeMeasureSpec(maxHeight.coerceAtMost(childLayoutHeight), EXACTLY) + } else { + makeMeasureSpec(maxHeight, AT_MOST) + } + measureChildWithMargins(child, widthMeasureSpec, 0, childHeightSpec, 0) + val childMeasuredHeight = child.measuredHeight + + val ownHeightMode = MeasureSpec.getMode(heightMeasureSpec) + val ownHeightSize = MeasureSpec.getSize(heightMeasureSpec) + + val ownMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec) + val ownMeasuredHeight = + if (ownHeightMode != UNSPECIFIED) { + childMeasuredHeight.coerceAtMost(ownHeightSize) + } else { + childMeasuredHeight + } + + setMeasuredDimension(ownMeasuredWidth, ownMeasuredHeight) + } } private val PromotedNotificationContentModel.layoutResource: Int? @@ -521,6 +584,11 @@ private enum class AodPromotedNotificationColor(val colorInt: Int) { val brush = SolidColor(androidx.compose.ui.graphics.Color(colorInt)) } +@Composable +private fun scaledFontHeight(@DimenRes dimenId: Int): Dp { + return dimensionResource(dimenId) * LocalDensity.current.fontScale.coerceAtLeast(1f) +} + private val viewUpdaterTagId = systemuiR.id.aod_promoted_notification_view_updater_tag private const val TAG = "AODPromotedNotification" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index e76867373139..b0b08a928f6c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -343,7 +343,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } protected boolean usesTransparentBackground() { - return false; + return mIsBlurSupported && notificationRowTransparency(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 76830646587d..256d549dc880 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -22,9 +22,9 @@ import static android.service.notification.NotificationListenerService.REASON_CA import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_EXPANDED; import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED; +import static com.android.systemui.Flags.notificationRowAccessibilityExpanded; import static com.android.systemui.Flags.notificationRowTransparency; import static com.android.systemui.Flags.notificationsPinnedHunInShade; -import static com.android.systemui.Flags.notificationRowAccessibilityExpanded; import static com.android.systemui.flags.Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE; import static com.android.systemui.statusbar.notification.NotificationUtils.logKey; import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED; @@ -41,6 +41,7 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Path; import android.graphics.Point; import android.graphics.Rect; @@ -422,9 +423,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } onExpansionChanged(true /* userAction */, wasExpanded); } else { - final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry); - boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(mEntry); - mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded); + final boolean wasExpanded = + mGroupExpansionManager.isGroupExpanded(getEntryLegacy()); + boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(getEntryLegacy()); + mOnExpandClickListener.onExpandClicked(getEntryLegacy(), v, nowExpanded); if (shouldLogExpandClickMetric) { mMetricsLogger.action( MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER, nowExpanded); @@ -454,7 +456,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { mOnExpandClickListener.onExpandClicked(this, mEntryAdapter, nowExpanded); } else { - mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded); + mOnExpandClickListener.onExpandClicked(getEntryLegacy(), v, nowExpanded); } if (shouldLogExpandClickMetric) { mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_EXPANDER, nowExpanded); @@ -559,7 +561,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { return mKey; } else { - return mEntry.getKey(); + return getEntryLegacy().getKey(); } } @@ -662,15 +664,20 @@ public class ExpandableNotificationRow extends ActivatableNotificationView */ public boolean getIsNonblockable() { NotificationBundleUi.assertInLegacyMode(); - if (mEntry == null) { + if (getEntryLegacy() == null) { return true; } - return !mEntry.isBlockable(); + return !getEntryLegacy().isBlockable(); } private boolean isConversation() { - return mPeopleNotificationIdentifier.getPeopleNotificationType(mEntry) - != PeopleNotificationIdentifier.TYPE_NON_PERSON; + if (NotificationBundleUi.isEnabled()) { + return getEntryAdapter().getPeopleNotificationType() + != PeopleNotificationIdentifier.TYPE_NON_PERSON; + } else { + return mPeopleNotificationIdentifier.getPeopleNotificationType(getEntryLegacy()) + != PeopleNotificationIdentifier.TYPE_NON_PERSON; + } } public void onNotificationUpdated() { @@ -680,7 +687,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView Trace.beginSection("ExpNotRow#onNotifUpdated (leaf)"); } for (NotificationContentView l : mLayouts) { - l.onNotificationUpdated(mEntry); + l.onNotificationUpdated(getEntry()); } mShowingPublicInitialized = false; if (mMenuRow != null) { @@ -747,7 +754,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView */ public void updateBubbleButton() { for (NotificationContentView l : mLayouts) { - l.updateBubbleButton(mEntry); + l.updateBubbleButton(getEntry()); } } @@ -778,7 +785,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mEntryAdapter.getContrastedColor(mContext, mIsMinimized && !isExpanded(), getBackgroundColorWithoutTint()); } else { - return mEntry.getContrastedColor(mContext, mIsMinimized && !isExpanded(), + return getEntryLegacy().getContrastedColor(mContext, mIsMinimized && !isExpanded(), getBackgroundColorWithoutTint()); } } @@ -886,7 +893,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { targetSdk = mEntryAdapter.getTargetSdk(); } else { - targetSdk = mEntry.targetSdk; + targetSdk = getEntryLegacy().targetSdk; } boolean beforeN = targetSdk < Build.VERSION_CODES.N; @@ -902,7 +909,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { summarization = mEntryAdapter.getSummarization(); } else { - summarization = mEntry.getRanking().getSummarization(); + summarization = getEntryLegacy().getRanking().getSummarization(); } if (customView && beforeS && !mIsSummaryWithChildren) { @@ -946,7 +953,25 @@ public class ExpandableNotificationRow extends ActivatableNotificationView layout.setHeights(smallHeight, headsUpHeight, maxExpandedHeight); } + /** + * Check {@link NotificationBundleUi#isEnabled()} + * and use {@link #getEntryAdapter()} when true + * and {@link #getEntryLegacy()} when false. + */ @NonNull + @Deprecated + public NotificationEntry getEntryLegacy() { + NotificationBundleUi.assertInLegacyMode(); + return mEntry; + } + + /** + * Check {@link NotificationBundleUi#isEnabled()} + * and use {@link #getEntryAdapter()} when true + * and {@link #getEntryLegacy()} when false. + */ + @NonNull + @Deprecated public NotificationEntry getEntry() { return mEntry; } @@ -1482,8 +1507,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public void setBubbleClickListener(@Nullable OnClickListener l) { mBubbleClickListener = l; // ensure listener is passed to the content views - mPrivateLayout.updateBubbleButton(mEntry); - mPublicLayout.updateBubbleButton(mEntry); + mPrivateLayout.updateBubbleButton(getEntry()); + mPublicLayout.updateBubbleButton(getEntry()); } /** @@ -1555,7 +1580,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return initializationTime != -1 && SystemClock.elapsedRealtime() > initializationTime + INITIALIZATION_DELAY; } else { - return getEntry().hasFinishedInitialization(); + return getEntryLegacy().hasFinishedInitialization(); } } @@ -1634,14 +1659,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { mEntryAdapter.prepareForInflation(); } else { - mEntry.getSbn().clearPackageContext(); + getEntryLegacy().getSbn().clearPackageContext(); } // TODO: Move content inflation logic out of this call RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); params.setNeedsReinflation(true); var rebindEndCallback = mRebindingTracker.trackRebinding(NotificationBundleUi.isEnabled() - ? mEntryAdapter.getKey() : mEntry.getKey()); + ? mEntryAdapter.getKey() : getEntryLegacy().getKey()); mRowContentBindStage.requestRebind(mEntry, (e) -> rebindEndCallback.onFinished()); Trace.endSection(); } @@ -1681,8 +1706,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView protected void setBackgroundTintColor(int color) { if (notificationRowTransparency()) { boolean isColorized = false; - if (NotificationBundleUi.isEnabled() && mEntryAdapter != null) { - isColorized = mEntryAdapter.isColorized(); + if (NotificationBundleUi.isEnabled()) { + if (mEntryAdapter != null) { + isColorized = mEntryAdapter.isColorized(); + } } else { if (mEntry != null) { isColorized = mEntry.getSbn().getNotification().isColorized(); @@ -1702,7 +1729,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } } - super.setBackgroundTintColor(color); NotificationContentView view = getShowingLayout(); if (view != null) { @@ -1765,7 +1791,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView /** @return true if the User has dismissed this notif's parent */ public boolean isParentDismissed() { - return getEntry().getDismissState() == PARENT_DISMISSED; + if (NotificationBundleUi.isEnabled()) { + return getEntryAdapter().getDismissState() == PARENT_DISMISSED; + } else { + return getEntryLegacy().getDismissState() == PARENT_DISMISSED; + } } @Override @@ -2325,7 +2355,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } @VisibleForTesting - protected void setEntry(NotificationEntry entry) { + @Deprecated + protected void setEntryLegacy(NotificationEntry entry) { + NotificationBundleUi.assertInLegacyMode(); mEntry = entry; } @@ -2418,7 +2450,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { return traceTag + "(" + getEntryAdapter().getStyle() + ")"; } else { - return traceTag + "(" + getEntry().getNotificationStyle() + ")"; + return traceTag + "(" + getEntryLegacy().getNotificationStyle() + ")"; } } @@ -2488,7 +2520,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView */ public void dragAndDropSuccess() { if (mOnDragSuccessListener != null) { - mOnDragSuccessListener.onDragSuccess(getEntry()); + if (NotificationBundleUi.isEnabled()) { + mOnDragSuccessListener.onDragSuccess(getEntryAdapter()); + } else { + mOnDragSuccessListener.onDragSuccess(getEntryLegacy()); + } } } @@ -2923,7 +2959,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { return getEntryAdapter().getIcons().getShelfIcon(); } else { - return mEntry.getIcons().getShelfIcon(); + return getEntryLegacy().getIcons().getShelfIcon(); } } @@ -3031,7 +3067,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mGroupExpansionManager.setGroupExpanded(mEntryAdapter, userExpanded); } } else { - mGroupExpansionManager.setGroupExpanded(mEntry, userExpanded); + mGroupExpansionManager.setGroupExpanded(getEntryLegacy(), userExpanded); } onExpansionChanged(true /* userAction */, wasExpanded); return; @@ -3174,7 +3210,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public boolean canShowHeadsUp() { boolean canEntryHun = NotificationBundleUi.isEnabled() ? mEntryAdapter.canPeek() - : mEntry.isStickyAndNotDemoted(); + : getEntryLegacy().isStickyAndNotDemoted(); if (mOnKeyguard && !isDozing() && !isBypassEnabled() && (!canEntryHun || (!mIgnoreLockscreenConstraints && mSaveSpaceOnLockscreen))) { @@ -3196,13 +3232,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { return mGroupExpansionManager.isGroupExpanded(mEntryAdapter); } - return mGroupExpansionManager.isGroupExpanded(mEntry); + return mGroupExpansionManager.isGroupExpanded(getEntryLegacy()); } private boolean isGroupRoot() { return NotificationBundleUi.isEnabled() ? mGroupMembershipManager.isGroupRoot(mEntryAdapter) - : mGroupMembershipManager.isGroupSummary(mEntry); + : mGroupMembershipManager.isGroupSummary(getEntryLegacy()); } private void onAttachedChildrenCountChanged() { @@ -3224,7 +3260,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { mPublicLayout.setNotificationWhen(mEntryAdapter.getWhen()); } else { - mPublicLayout.setNotificationWhen(mEntry.getSbn().getNotification().getWhen()); + mPublicLayout.setNotificationWhen( + getEntryLegacy().getSbn().getNotification().getWhen()); } } getShowingLayout().updateBackgroundColor(false /* animate */); @@ -3559,7 +3596,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mEntryAdapter.isClearable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral); } else { - return mEntry.isClearable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral); + return getEntryLegacy().isClearable() + && (!shouldShowPublic() || !mSensitiveHiddenInGeneral); } } @@ -3573,7 +3611,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (!NotificationBundleUi.isEnabled()) { // this is only called if row.getParent() instanceof NotificationStackScrollLayout, // so there is never a group to expand - mGroupExpansionManager.setGroupExpanded(mEntry, true); + mGroupExpansionManager.setGroupExpanded(getEntryLegacy(), true); } } notifyHeightChanged(/* needsAnimation= */ false); @@ -3806,7 +3844,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return true; } } else { - if (getEntry().getSbn().getNotification().isColorized()) { + if (getEntryLegacy().getSbn().getNotification().isColorized()) { return true; } } @@ -3973,12 +4011,18 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } else if (isChildInGroup()) { final int childColor = getShowingLayout().getBackgroundColorForExpansionState(); - // Only show a background if the group is expanded OR if it is expanding / collapsing - // and has a custom background color. - final boolean showBackground = isGroupExpanded() - || ((mNotificationParent.isGroupExpansionChanging() - || mNotificationParent.isUserLocked()) && childColor != 0); - mShowNoBackground = !showBackground; + if (Flags.notificationRowTransparency() && childColor == Color.TRANSPARENT) { + // If child is not customizing its background color, switch from the parent to + // the child background when the expansion finishes. + mShowNoBackground = !mNotificationParent.mShowNoBackground; + } else { + // Only show a background if the group is expanded OR if it is + // expanding / collapsing and has a custom background color. + final boolean showBackground = isGroupExpanded() + || ((mNotificationParent.isGroupExpansionChanging() + || mNotificationParent.isUserLocked()) && childColor != 0); + mShowNoBackground = !showBackground; + } } else { // Only children or parents ever need no background. mShowNoBackground = false; @@ -4277,7 +4321,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public boolean isMediaRow() { NotificationBundleUi.assertInLegacyMode(); - return mEntry.getSbn().getNotification().isMediaNotification(); + return getEntryLegacy().getSbn().getNotification().isMediaNotification(); } public void setAboveShelf(boolean aboveShelf) { @@ -4381,6 +4425,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * @param entry NotificationEntry that succeed to drop on proper target window. */ void onDragSuccess(NotificationEntry entry); + + /** + * @param entryAdapter The EntryAdapter that successfully dropped on the proper + * target window + */ + void onDragSuccess(EntryAdapter entryAdapter); } /** @@ -4399,11 +4449,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public void dump(PrintWriter pwOriginal, String[] args) { IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal); // Skip super call; dump viewState ourselves - if (NotificationBundleUi.isEnabled()) { - pw.println("Notification: " + mEntryAdapter.getKey()); - } else { - pw.println("Notification: " + mEntry.getKey()); - } + pw.println("Notification: " + getKey()); DumpUtilsKt.withIncreasedIndent(pw, () -> { pw.println(this); pw.print("visibility: " + getVisibility()); @@ -4640,7 +4686,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { mLaunchAnimationRunning = launchAnimationRunning; } else { - getEntry().setExpandAnimationRunning(launchAnimationRunning); + getEntryLegacy().setExpandAnimationRunning(launchAnimationRunning); } } @@ -4649,7 +4695,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (NotificationBundleUi.isEnabled()) { return mLaunchAnimationRunning; } else { - return getEntry().isExpandAnimationRunning(); + return getEntryLegacy().isExpandAnimationRunning(); } } @@ -4657,8 +4703,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView protected boolean usesTransparentBackground() { // Row background should be opaque when it's displayed as a heads-up notification or // displayed on keyguard. - // TODO(b/388891313): Account for isBlurSupported when it is initialized and updated - // correctly. - return notificationRowTransparency() && !mIsHeadsUp && !mOnKeyguard; + return super.usesTransparentBackground() && !mIsHeadsUp && !mOnKeyguard; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index ac55930f5c11..49d715cfc84f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.notification.NotificationUtils.logKey; +import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import android.net.Uri; import android.os.UserHandle; @@ -35,8 +36,8 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; +import com.android.systemui.Flags; import com.android.systemui.flags.FeatureFlagsClassic; -import com.android.systemui.flags.Flags; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; @@ -45,11 +46,8 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.FeedbackIcon; -import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory; -import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl; import com.android.systemui.statusbar.notification.collection.PipelineEntry; -import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; @@ -60,7 +58,6 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden import com.android.systemui.statusbar.notification.row.dagger.AppName; import com.android.systemui.statusbar.notification.row.dagger.NotificationKey; import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope; -import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider; import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -69,6 +66,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.SmartReplyConstants; import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.util.time.SystemClock; +import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor; import com.google.android.msdl.data.model.MSDLToken; import com.google.android.msdl.domain.MSDLPlayer; @@ -125,6 +123,7 @@ public class ExpandableNotificationRowController implements NotifViewController private final MSDLPlayer mMSDLPlayer; private final NotificationSettingsController mSettingsController; private final EntryAdapterFactory mEntryAdapterFactory; + private final WindowRootViewBlurInteractor mWindowRootViewBlurInteractor; @VisibleForTesting final NotificationSettingsController.Listener mSettingsListener = @@ -139,7 +138,7 @@ public class ExpandableNotificationRowController implements NotifViewController } final int viewUserId = NotificationBundleUi.isEnabled() ? mView.getEntryAdapter().getSbn().getUserId() - : mView.getEntry().getSbn().getUserId(); + : mView.getEntryLegacy().getSbn().getUserId(); if (viewUserId == UserHandle.USER_ALL || viewUserId == userId) { mView.getPrivateLayout().setBubblesEnabledForUser( BUBBLES_SETTING_ENABLED_VALUE.equals(value)); @@ -291,7 +290,8 @@ public class ExpandableNotificationRowController implements NotifViewController UiEventLogger uiEventLogger, MSDLPlayer msdlPlayer, NotificationRebindingTracker notificationRebindingTracker, - EntryAdapterFactory entryAdapterFactory) { + EntryAdapterFactory entryAdapterFactory, + WindowRootViewBlurInteractor windowRootViewBlurInteractor) { mView = view; mListContainer = listContainer; mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory; @@ -329,6 +329,7 @@ public class ExpandableNotificationRowController implements NotifViewController mUiEventLogger = uiEventLogger; mMSDLPlayer = msdlPlayer; mEntryAdapterFactory = entryAdapterFactory; + mWindowRootViewBlurInteractor = windowRootViewBlurInteractor; } /** @@ -367,7 +368,8 @@ public class ExpandableNotificationRowController implements NotifViewController ); mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); if (mAllowLongPress) { - if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_DRAG_TO_CONTENTS)) { + if (mFeatureFlags.isEnabled( + com.android.systemui.flags.Flags.NOTIFICATION_DRAG_TO_CONTENTS)) { mView.setDragController(mDragController); } @@ -395,7 +397,7 @@ public class ExpandableNotificationRowController implements NotifViewController mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener); } } else { - mView.getEntry().setInitializationTime(mClock.elapsedRealtime()); + mView.getEntryLegacy().setInitializationTime(mClock.elapsedRealtime()); mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener); } mPluginManager.addPluginListener(mView, @@ -416,6 +418,11 @@ public class ExpandableNotificationRowController implements NotifViewController mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener); } }); + + if (Flags.notificationRowTransparency()) { + collectFlow(mView, mWindowRootViewBlurInteractor.isBlurCurrentlySupported(), + mView::setIsBlurSupported); + } } private final StatusBarStateController.StateListener mStatusBarStateListener = @@ -429,7 +436,9 @@ public class ExpandableNotificationRowController implements NotifViewController @Override @NonNull public String getNodeLabel() { - return NotificationBundleUi.isEnabled() ? mView.getLoggingKey() : logKey(mView.getEntry()); + return NotificationBundleUi.isEnabled() + ? mView.getLoggingKey() + : logKey(mView.getEntryLegacy()); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java index 9ae2eb1b9328..20b826a3ca92 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java @@ -109,7 +109,7 @@ public class ExpandableNotificationRowDragController { StatusBarNotification sn = NotificationBundleUi.isEnabled() ? enr.getEntryAdapter().getSbn() - : enr.getEntry().getSbn(); + : enr.getEntryLegacy().getSbn(); Notification notification = sn.getNotification(); final PendingIntent contentIntent = notification.contentIntent != null ? notification.contentIntent diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index ff4b835eb3c0..d97e25fdfa22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -473,7 +473,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder result.newPublicView = createSensitiveContentMessageNotification( NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSbn().getNotification() - : row.getEntry().getSbn().getNotification(), + : row.getEntryLegacy().getSbn().getNotification(), builder.getStyle(), systemUiContext, packageContext).createContentView(); } else { @@ -814,7 +814,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder existingWrapper.onReinflated(); } } catch (Exception e) { - handleInflationError(runningInflations, e, row, callback, logger, + handleInflationError(runningInflations, e, row, entry, callback, logger, "applying view synchronously"); // Add a running inflation to make sure we don't trigger callbacks. // Safe to do because only happens in tests. @@ -836,7 +836,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder String invalidReason = isValidView(v, entry, row.getResources()); if (invalidReason != null) { handleInflationError(runningInflations, new InflationException(invalidReason), - row, callback, logger, "applied invalid view"); + row, entry, callback, logger, "applied invalid view"); runningInflations.remove(inflationId); return; } @@ -873,7 +873,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder onViewApplied(newView); } catch (Exception anotherException) { runningInflations.remove(inflationId); - handleInflationError(runningInflations, e, row, + handleInflationError(runningInflations, e, row, entry, callback, logger, "applying view"); } } @@ -969,13 +969,14 @@ public class NotificationContentInflater implements NotificationRowContentBinder private static void handleInflationError( HashMap<Integer, CancellationSignal> runningInflations, Exception e, - ExpandableNotificationRow row, @Nullable InflationCallback callback, + ExpandableNotificationRow row, NotificationEntry entry, + @Nullable InflationCallback callback, NotificationRowContentBinderLogger logger, String logContext) { Assert.isMainThread(); logger.logAsyncTaskException(row.getLoggingKey(), logContext, e); runningInflations.values().forEach(CancellationSignal::cancel); if (callback != null) { - callback.handleInflationException(row.getEntry(), e); + callback.handleInflationException(entry, e); } } @@ -1443,7 +1444,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder + Integer.toHexString(sbn.getId()); Log.e(CentralSurfaces.TAG, "couldn't inflate view for notification " + ident, e); if (mCallback != null) { - mCallback.handleInflationException(mRow.getEntry(), + mCallback.handleInflationException(mEntry, new InflationException("Couldn't inflate contentViews" + e)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index b3357d01ab7a..cb1e898ef5b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -269,6 +269,7 @@ public class NotificationContentView extends FrameLayout implements Notification mNotificationMaxHeight = maxHeight; } + // This logic is mirrored in FrameLayoutWithMaxHeight.onMeasure in AODPromotedNotification.kt. @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int heightMode = MeasureSpec.getMode(heightMeasureSpec); @@ -600,7 +601,7 @@ public class NotificationContentView extends FrameLayout implements Notification if (NotificationBundleUi.isEnabled()) { return mContainingNotification.getEntryAdapter().getSbn(); } else { - return mContainingNotification.getEntry().getSbn(); + return mContainingNotification.getEntryLegacy().getSbn(); } } @@ -1592,20 +1593,26 @@ public class NotificationContentView extends FrameLayout implements Notification return; } ImageView bubbleButton = layout.findViewById(com.android.internal.R.id.bubble_button); - View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container); - ViewGroup actionListMarginTarget = layout.findViewById( - com.android.internal.R.id.notification_action_list_margin_target); - if (bubbleButton == null || actionContainer == null) { + // With the new design, the actions_container should always be visible to act as padding + // when there are no actions. We're making its child visible/invisible instead. + View actionsContainerForVisibilityChange = layout.findViewById( + notificationsRedesignTemplates() + ? com.android.internal.R.id.actions_container_layout + : com.android.internal.R.id.actions_container); + if (bubbleButton == null || actionsContainerForVisibilityChange == null) { return; } if (shouldShowBubbleButton(entry)) { + boolean isBubble = NotificationBundleUi.isEnabled() + ? mContainingNotification.getEntryAdapter().isBubbleCapable() + : entry.isBubble(); // explicitly resolve drawable resource using SystemUI's theme - Drawable d = mContext.getDrawable(entry.isBubble() + Drawable d = mContext.getDrawable(isBubble ? com.android.wm.shell.R.drawable.bubble_ic_stop_bubble : com.android.wm.shell.R.drawable.bubble_ic_create_bubble); - String contentDescription = mContext.getResources().getString(entry.isBubble() + String contentDescription = mContext.getResources().getString(isBubble ? R.string.notification_conversation_unbubble : R.string.notification_conversation_bubble); @@ -1613,17 +1620,14 @@ public class NotificationContentView extends FrameLayout implements Notification bubbleButton.setImageDrawable(d); bubbleButton.setOnClickListener(mContainingNotification.getBubbleClickListener()); bubbleButton.setVisibility(VISIBLE); - actionContainer.setVisibility(VISIBLE); - // Set notification_action_list_margin_target's bottom margin to 0 when showing bubble - if (actionListMarginTarget != null) { - removeBottomMargin(actionListMarginTarget); - } - if (notificationsRedesignTemplates()) { - // Similar treatment for smart reply margin - LinearLayout smartReplyContainer = layout.findViewById( - com.android.internal.R.id.smart_reply_container); - if (smartReplyContainer != null) { - removeBottomMargin(smartReplyContainer); + actionsContainerForVisibilityChange.setVisibility(VISIBLE); + if (!notificationsRedesignTemplates()) { + // Set notification_action_list_margin_target's bottom margin to 0 when showing + // bubble + ViewGroup actionListMarginTarget = layout.findViewById( + com.android.internal.R.id.notification_action_list_margin_target); + if (actionListMarginTarget != null) { + removeBottomMargin(actionListMarginTarget); } } } else { @@ -1651,12 +1655,18 @@ public class NotificationContentView extends FrameLayout implements Notification @VisibleForTesting boolean shouldShowBubbleButton(NotificationEntry entry) { - boolean isPersonWithShortcut = - mPeopleIdentifier.getPeopleNotificationType(entry) - >= PeopleNotificationIdentifier.TYPE_FULL_PERSON; + int peopleType = NotificationBundleUi.isEnabled() + ? mContainingNotification.getEntryAdapter().getPeopleNotificationType() + : mPeopleIdentifier.getPeopleNotificationType(entry); + Notification.BubbleMetadata bubbleMetadata = NotificationBundleUi.isEnabled() + ? mContainingNotification.getEntryAdapter().getSbn().getNotification() + .getBubbleMetadata() + : entry.getBubbleMetadata(); + boolean isPersonWithShortcut = peopleType + >= PeopleNotificationIdentifier.TYPE_FULL_PERSON; return mBubblesEnabledForUser && isPersonWithShortcut - && entry.getBubbleMetadata() != null; + && bubbleMetadata != null; } private void applySnoozeAction(View layout) { @@ -1664,8 +1674,13 @@ public class NotificationContentView extends FrameLayout implements Notification return; } ImageView snoozeButton = layout.findViewById(com.android.internal.R.id.snooze_button); - View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container); - if (snoozeButton == null || actionContainer == null) { + // With the new design, the actions_container should always be visible to act as padding + // when there are no actions. We're making its child visible/invisible instead. + View actionsContainerForVisibilityChange = layout.findViewById( + notificationsRedesignTemplates() + ? com.android.internal.R.id.actions_container_layout + : com.android.internal.R.id.actions_container); + if (snoozeButton == null || actionsContainerForVisibilityChange == null) { return; } // Notification.Builder can 'disable' the snooze button to prevent it from being shown here @@ -1691,7 +1706,7 @@ public class NotificationContentView extends FrameLayout implements Notification snoozeButton.setOnClickListener( mContainingNotification.getSnoozeClickListener(snoozeMenuItem)); snoozeButton.setVisibility(VISIBLE); - actionContainer.setVisibility(VISIBLE); + actionsContainerForVisibilityChange.setVisibility(VISIBLE); } private void applySmartReplyView() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index caa1d28cc914..cdb78d99538b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -47,7 +47,6 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.internal.statusbar.IStatusBarService; import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.CoreStartable; -import com.android.systemui.Flags; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; @@ -235,15 +234,6 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta } } - public void onDensityOrFontScaleChanged(NotificationEntry entry) { - if (!Flags.notificationUndoGutsOnConfigChanged()) { - Log.wtf(TAG, "onDensityOrFontScaleChanged should not be called if" - + " notificationUndoGutsOnConfigChanged is off"); - } - setExposedGuts(entry.getGuts()); - bindGuts(entry.getRow()); - } - /** * Sends an intent to open the notification settings for a particular package and optional * channel. @@ -295,11 +285,6 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta mNotificationActivityStarter.startNotificationGutsIntent(intent, uid, row); } - private boolean bindGuts(final ExpandableNotificationRow row) { - row.ensureGutsInflated(); - return bindGuts(row, mGutsMenuItem); - } - @VisibleForTesting protected boolean bindGuts(final ExpandableNotificationRow row, NotificationMenuRowPlugin.MenuItem item) { @@ -611,6 +596,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta return mNotificationGutsExposed; } + @VisibleForTesting public void setExposedGuts(NotificationGuts guts) { mNotificationGutsExposed = guts; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java index e89a76fd5a69..977936fa34fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java @@ -49,6 +49,7 @@ import com.android.systemui.statusbar.AlphaOptimizedImageView; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.NotificationGuts.GutsContent; +import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import java.util.ArrayList; @@ -261,15 +262,19 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl mSnoozeItem = createSnoozeItem(mContext); } mFeedbackItem = createFeedbackItem(mContext); - NotificationEntry entry = mParent.getEntry(); - int personNotifType = mPeopleNotificationIdentifier.getPeopleNotificationType(entry); + int personNotifType = NotificationBundleUi.isEnabled() + ? mParent.getEntryAdapter().getPeopleNotificationType() + : mPeopleNotificationIdentifier.getPeopleNotificationType(mParent.getEntryLegacy()); + StatusBarNotification sbn = NotificationBundleUi.isEnabled() + ? mParent.getEntryAdapter().getSbn() + : mParent.getEntryLegacy().getSbn(); if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) { mInfoItem = createPartialConversationItem(mContext); } else if (personNotifType >= PeopleNotificationIdentifier.TYPE_FULL_PERSON) { mInfoItem = createConversationItem(mContext); } else if (android.app.Flags.uiRichOngoing() && Flags.permissionHelperUiRichOngoing() - && entry.getSbn().getNotification().isPromotedOngoing()) { + && sbn.getNotification().isPromotedOngoing()) { mInfoItem = createPromotedItem(mContext); } else { mInfoItem = createInfoItem(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt index 2f94d3220dc8..ae52db88358a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt @@ -541,7 +541,7 @@ constructor( val ident: String = (sbn.packageName + "/0x" + Integer.toHexString(sbn.id)) Log.e(TAG, "couldn't inflate view for notification $ident", e) callback?.handleInflationException( - if (NotificationBundleUi.isEnabled) entry else row.entry, + if (NotificationBundleUi.isEnabled) entry else row.entryLegacy, InflationException("Couldn't inflate contentViews$e"), ) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java index 83897f5bc3a7..cec0ae696b26 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java @@ -51,7 +51,6 @@ import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Flags; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; import com.android.systemui.res.R; @@ -477,7 +476,7 @@ public class NotificationSnooze extends LinearLayout @Override public boolean handleCloseControls(boolean save, boolean force) { - if (Flags.notificationUndoGutsOnConfigChanged() && !save) { + if (!save) { // Undo changes and let the guts handle closing the view mSelectedOption = null; showSnoozeOptions(false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt index 08c1d71b86c9..03990bf3af84 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt @@ -87,9 +87,15 @@ constructor(private val userManager: UserManager, dumpManager: DumpManager) : // It's not a system app at all. return false } else { - // If there's no launch intent, it's probably a headless app. - val pm = context.packageManager - return (pm.getLaunchIntentForPackage(info.packageName) == null) + // If there's no launch intent, it's probably a headless app. Check for both + // direct-aware and -unaware intents; otherwise this will almost certainly fail + // for notifications posted before unlocking. + val packageLaunchIntent = + context.packageManager.getLaunchIntentForPackage( + info.packageName, + /* includeDirectBootUnaware= */ true, + ) + return packageLaunchIntent == null } } else { // If for some reason we don't have the app info, we don't know; best assume it's diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt index 4082a5b35f1e..2c5b9f44bc58 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt @@ -61,7 +61,7 @@ constructor( row: ExpandableNotificationRow, context: Context, ): NotificationIconProvider { - val sbn = if (NotificationBundleUi.isEnabled) row.entryAdapter?.sbn else row.entry.sbn + val sbn = if (NotificationBundleUi.isEnabled) row.entryAdapter?.sbn else row.entryLegacy.sbn if (sbn == null) { return object : NotificationIconProvider { override fun shouldShowAppIcon(): Boolean { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt index 8984f2c4220d..f0b5c3667962 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt @@ -50,15 +50,6 @@ object ActivatableNotificationViewBinder { view.registerListenersWhileAttached(touchHandler) } } - view.repeatWhenAttached { - repeatOnLifecycle(Lifecycle.State.STARTED) { - launch { - viewModel.isBlurSupported.collect { supported -> - view.setIsBlurSupported(supported) - } - } - } - } } private suspend fun ActivatableNotificationView.registerListenersWhileAttached( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt index 9a86ffbe33b6..2d2fd6082cac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification.row.ui.viewmodel import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor -import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor import dagger.Module import dagger.Provides import kotlinx.coroutines.flow.Flow @@ -27,26 +26,21 @@ import kotlinx.coroutines.flow.map interface ActivatableNotificationViewModel : ExpandableOutlineViewModel { /** Does the view react to touches? */ val isTouchable: Flow<Boolean> - val isBlurSupported: Flow<Boolean> companion object { operator fun invoke( a11yInteractor: AccessibilityInteractor, - windowRootViewBlurInteractor: WindowRootViewBlurInteractor ): ActivatableNotificationViewModel = - ActivatableNotificationViewModelImpl(a11yInteractor, windowRootViewBlurInteractor) + ActivatableNotificationViewModelImpl(a11yInteractor) } } private class ActivatableNotificationViewModelImpl( a11yInteractor: AccessibilityInteractor, - windowRootViewBlurInteractor: WindowRootViewBlurInteractor, ) : ActivatableNotificationViewModel { override val isTouchable: Flow<Boolean> = // If a11y touch exploration is enabled, then the activatable view should ignore touches a11yInteractor.isTouchExplorationEnabled.map { !it } - override val isBlurSupported: Flow<Boolean> = - windowRootViewBlurInteractor.isBlurCurrentlySupported } @Module @@ -54,7 +48,6 @@ object ActivatableNotificationViewModelModule { @Provides fun provideViewModel( a11yInteractor: AccessibilityInteractor, - windowRootViewBlurInteractor: WindowRootViewBlurInteractor ) = - ActivatableNotificationViewModel(a11yInteractor, windowRootViewBlurInteractor) + ActivatableNotificationViewModel(a11yInteractor) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java index f492b259e58d..e266dad63d80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java @@ -50,7 +50,7 @@ public class NotificationBigPictureTemplateViewWrapper extends NotificationTempl resolveViews(); updateImageTag(NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSbn() - : row.getEntry().getSbn()); + : row.getEntryLegacy().getSbn()); } private void resolveViews() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java index dec674c5a0f3..71bb9a2c9e72 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java @@ -47,7 +47,7 @@ public class NotificationBigTextTemplateViewWrapper extends NotificationTemplate // the transformation types and we need to have our values set by then. resolveViews(NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSbn() - : row.getEntry().getSbn()); + : row.getEntryLegacy().getSbn()); super.onContentUpdated(row); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java index 585051ad26e1..e6dadcd7c8d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java @@ -225,7 +225,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple super.onContentUpdated(row); mIsLowPriority = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().isAmbient() - : row.getEntry().isAmbient(); + : row.getEntryLegacy().isAmbient(); mTransformLowPriorityTitle = !row.isChildInGroup() && !row.isSummaryWithChildren(); ArraySet<View> previousViews = mTransformationHelper.getAllTransformingViews(); @@ -236,7 +236,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple updateCropToPaddingForImageViews(); Notification n = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSbn().getNotification() - : row.getEntry().getSbn().getNotification(); + : row.getEntryLegacy().getSbn().getNotification(); mIcon.setTag(ImageTransformState.ICON_TAG, n.getSmallIcon()); // We need to reset all views that are no longer transforming in case a view was previously diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java index 99db1dba7e65..19321dcef5c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java @@ -327,7 +327,7 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp // the transformation types and we need to have our values set by then. resolveTemplateViews(NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSbn() - : row.getEntry().getSbn()); + : row.getEntryLegacy().getSbn()); super.onContentUpdated(row); // With the modern templates, a large icon visually overlaps the header, so we can't // hide the header, we must show it. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java index 64babb2449d7..35e286c18fd8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java @@ -83,7 +83,7 @@ public abstract class NotificationViewWrapper implements TransformableView { if (NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSbn().getNotification().isStyle( Notification.DecoratedCustomViewStyle.class) - : row.getEntry().getSbn().getNotification().isStyle( + : row.getEntryLegacy().getSbn().getNotification().isStyle( Notification.DecoratedCustomViewStyle.class)) { return new NotificationDecoratedCustomViewWrapper(ctx, v, row); } @@ -141,7 +141,7 @@ public abstract class NotificationViewWrapper implements TransformableView { // Apps targeting Q should fix their dark mode bugs. int targetSdk = NotificationBundleUi.isEnabled() ? mRow.getEntryAdapter().getTargetSdk() - : mRow.getEntry().targetSdk; + : mRow.getEntryLegacy().targetSdk; if (targetSdk >= Build.VERSION_CODES.Q) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt index f663ea019319..a75330b329d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.shelf.ui.viewbinder import com.android.app.tracing.coroutines.launchTraced as launch import com.android.app.tracing.traceSection +import com.android.systemui.Flags import com.android.systemui.plugins.FalsingManager import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.NotificationShelf @@ -47,6 +48,10 @@ object NotificationShelfViewBinder { launch { viewModel.isAlignedToEnd.collect(::setAlignedToEnd) } } + if (Flags.notificationRowTransparency()) { + launch { viewModel.isBlurSupported.collect(shelf::setIsBlurSupported) } + } + registerViewListenersWhileAttached(shelf, viewModel) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt index 96cdda6d4a23..9eb1ece63846 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt @@ -21,6 +21,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.statusbar.NotificationShelf import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor +import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf @@ -32,6 +33,7 @@ class NotificationShelfViewModel @Inject constructor( private val interactor: NotificationShelfInteractor, + windowRootViewBlurInteractor: WindowRootViewBlurInteractor, activatableViewModel: ActivatableNotificationViewModel, ) : ActivatableNotificationViewModel by activatableViewModel { /** Is the shelf allowed to be clickable when it has content? */ @@ -51,6 +53,8 @@ constructor( } } + val isBlurSupported: Flow<Boolean> = windowRootViewBlurInteractor.isBlurCurrentlySupported + /** Notifies that the user has clicked the shelf. */ fun onShelfClicked() { interactor.goToLockedShadeFromShelf() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index abfb86244390..fc7b24e7f625 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -696,10 +696,13 @@ public class AmbientState implements Dumpable { return mPulsing; } + public boolean isPulsing(String entryKey) { + boolean isHeadsUp = mHeadsUpRepository.isHeadsUpEntry(entryKey); + return mPulsing && isHeadsUp; + } + public boolean isPulsing(NotificationEntry entry) { - boolean isHeadsUp = NotificationBundleUi.isEnabled() - ? mHeadsUpRepository.isHeadsUpEntry(entry.getKey()) - : entry.isHeadsUpEntry(); + boolean isHeadsUp = entry.isHeadsUpEntry(); return mPulsing && isHeadsUp; } @@ -750,7 +753,10 @@ public class AmbientState implements Dumpable { * @return whether a row is dozing and not pulsing right now */ public boolean isDozingAndNotPulsing(ExpandableNotificationRow row) { - return isDozing() && !isPulsing(row.getEntry()); + boolean isPulsing = NotificationBundleUi.isEnabled() + ? isPulsing(row.getKey()) + : isPulsing(row.getEntryLegacy()); + return isDozing() && !isPulsing; } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt index 9bd5a5bd903f..5a23f7cc2861 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt @@ -181,7 +181,7 @@ constructor( it.setMagneticTranslation(targetTranslation) } } - playPullHaptics(mappedTranslation = swipedRowMultiplier * translation, canSwipedBeDismissed) + // TODO(b/399633875): Enable pull haptics after we have a clear and polished haptics design } private fun playPullHaptics(mappedTranslation: Float, canSwipedBeDismissed: Boolean) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java index 315d37e55bc3..f9d8c8e74b5d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java @@ -444,7 +444,7 @@ public class NotificationChildrenContainer extends ViewGroup mIsConversation = isConversation; StatusBarNotification notification = NotificationBundleUi.isEnabled() ? mContainingNotification.getEntryAdapter().getSbn() - : mContainingNotification.getEntry().getSbn(); + : mContainingNotification.getEntryLegacy().getSbn(); if (notification == null) { return; } @@ -615,7 +615,7 @@ public class NotificationChildrenContainer extends ViewGroup RemoteViews header; StatusBarNotification notification = NotificationBundleUi.isEnabled() ? mContainingNotification.getEntryAdapter().getSbn() - : mContainingNotification.getEntry().getSbn(); + : mContainingNotification.getEntryLegacy().getSbn(); if (notification == null) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt index 96f0e6f57958..b5562ae15ede 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt @@ -167,7 +167,7 @@ internal constructor( view === promoHeaderView -> BUCKET_PROMO view is ExpandableNotificationRow -> if (NotificationBundleUi.isEnabled) view.entryAdapter?.sectionBucket - else view.entry.bucket + else view.entryLegacy.bucket else -> null } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index a5f711050c46..9fea75048e3e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -1039,10 +1039,10 @@ public class NotificationStackScrollLayout } int bucket = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSectionBucket() - : row.getEntry().getBucket(); + : row.getEntryLegacy().getBucket(); boolean isAmbient = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().isAmbient() - : row.getEntry().isAmbient(); + : row.getEntryLegacy().isAmbient(); currentIndex++; boolean beforeSpeedBump; if (mHighPriorityBeforeSpeedBump) { @@ -1847,7 +1847,7 @@ public class NotificationStackScrollLayout } else { if (row.isChildInGroup()) { final NotificationEntry groupSummary = - mGroupMembershipManager.getGroupSummary(row.getEntry()); + mGroupMembershipManager.getGroupSummary(row.getEntryLegacy()); if (groupSummary != null) { row = groupSummary.getRow(); } @@ -2000,16 +2000,16 @@ public class NotificationStackScrollLayout if ((bottom - top >= mMinInteractionHeight || !requireMinHeight) && touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) { if (slidingChild instanceof ExpandableNotificationRow row) { - NotificationEntry entry = row.getEntry(); boolean isEntrySummaryForTopHun; if (NotificationBundleUi.isEnabled()) { isEntrySummaryForTopHun = Objects.equals( ((ExpandableNotificationRow) slidingChild).getNotificationParent(), mTopHeadsUpRow); } else { + NotificationEntry entry = row.getEntryLegacy(); isEntrySummaryForTopHun = mTopHeadsUpRow != null && - mGroupMembershipManager.getGroupSummary(mTopHeadsUpRow.getEntry()) - == entry; + mGroupMembershipManager.getGroupSummary( + mTopHeadsUpRow.getEntryLegacy()) == entry; } if (!mIsExpanded && row.isHeadsUp() && row.isPinned() && mTopHeadsUpRow != row @@ -3009,7 +3009,7 @@ public class NotificationStackScrollLayout ExpandableNotificationRow childRow = (ExpandableNotificationRow) child; return NotificationBundleUi.isEnabled() ? mGroupMembershipManager.isChildInGroup(childRow.getEntryAdapter()) - : mGroupMembershipManager.isChildInGroup(childRow.getEntry()); + : mGroupMembershipManager.isChildInGroup(childRow.getEntryLegacy()); } return false; } @@ -6473,7 +6473,7 @@ public class NotificationStackScrollLayout @SelectedRows int selection) { int bucket = NotificationBundleUi.isEnabled() ? row.getEntryAdapter().getSectionBucket() - : row.getEntry().getBucket(); + : row.getEntryLegacy().getBucket(); switch (selection) { case ROWS_ALL: return true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index bb3abc1fba38..f3d8ee245540 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -648,11 +648,11 @@ public class NotificationStackScrollLayoutController implements Dumpable { public void onChildSnappedBack(View animView, float targetLeft) { mView.onSwipeEnd(); if (animView instanceof ExpandableNotificationRow row) { - if (row.isPinned() && !canChildBeDismissed(row) - && NotificationBundleUi.isEnabled() + boolean cannotFullScreen = NotificationBundleUi.isEnabled() ? !row.getEntryAdapter().isFullScreenCapable() - : (row.getEntry().getSbn().getNotification().fullScreenIntent - == null)) { + : (row.getEntryLegacy().getSbn().getNotification().fullScreenIntent + == null); + if (row.isPinned() && !canChildBeDismissed(row) && cannotFullScreen) { mHeadsUpManager.removeNotification( row.getKey(), /* removeImmediately= */ true, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt index fcb63df1a528..e5071d9c1e53 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt @@ -413,7 +413,7 @@ constructor( (currentNotification as? ExpandableNotificationRow)?.entryAdapter counter.incrementForBucket(entryAdapter?.sectionBucket) } else { - val entry = (currentNotification as? ExpandableNotificationRow)?.entry + val entry = (currentNotification as? ExpandableNotificationRow)?.entryLegacy counter.incrementForBucket(entry?.bucket) } } @@ -470,7 +470,7 @@ constructor( calculateGapAndDividerHeight(stack, previousView, current = view, visibleIndex) val canPeek = view is ExpandableNotificationRow && if (NotificationBundleUi.isEnabled) view.entryAdapter?.canPeek() == true - else view.entry.isStickyAndNotDemoted + else view.entryLegacy.isStickyAndNotDemoted var size = if (onLockscreen) { 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 28218227506c..da1442359071 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 @@ -927,7 +927,7 @@ public class StackScrollAlgorithm { childState.headsUpIsVisible, row.showingPulsing(), ambientState.isOnKeyguard(), NotificationBundleUi.isEnabled() ? row.getEntryAdapter().canPeek() - : row.getEntry().isStickyAndNotDemoted())) { + : row.getEntryLegacy().isStickyAndNotDemoted())) { // the height of this child before clamping it to the top float unmodifiedChildHeight = childState.height; clampHunToTop( @@ -984,7 +984,7 @@ public class StackScrollAlgorithm { childState.headsUpIsVisible, row.showingPulsing(), ambientState.isOnKeyguard(), NotificationBundleUi.isEnabled() ? row.getEntryAdapter().canPeek() - : row.getEntry().isStickyAndNotDemoted())) { + : row.getEntryLegacy().isStickyAndNotDemoted())) { // Ensure that the heads up is always visible even when scrolled off. // NSSL y starts at top of screen in non-split-shade, but below the qs // offset diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt index bc533148f514..afe79718d526 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt @@ -60,7 +60,7 @@ constructor( if (animationsEnabled) { added.forEach { key -> val row = obtainView(key) - val hasStatusBarChip = statusBarChips.contains(row.entry.key) + val hasStatusBarChip = statusBarChips.contains(row.key) parentView.generateHeadsUpAnimation( row, /* isHeadsUp = */ true, @@ -69,7 +69,7 @@ constructor( } removed.forEach { key -> val row = obtainView(key) - val hasStatusBarChip = statusBarChips.contains(row.entry.key) + val hasStatusBarChip = statusBarChips.contains(row.key) if (!parentView.isBeingDragged()) { parentView.generateHeadsUpAnimation( row, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java index 36193bd87ce2..3c144625b685 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java @@ -49,6 +49,7 @@ import com.android.keyguard.CarrierTextController; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.logging.KeyguardLogger; +import com.android.systemui.Flags; import com.android.systemui.battery.BatteryMeterViewController; import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor; import com.android.systemui.dagger.qualifiers.Background; @@ -475,12 +476,14 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat UserHandle.USER_ALL); updateUserSwitcher(); onThemeChanged(); - collectFlow(mView, mCommunalSceneInteractor.isCommunalVisible(), mCommunalConsumer, - mCoroutineDispatcher); - collectFlow(mView, mLockscreenToHubTransitionViewModel.getStatusBarAlpha(), - mToGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher); - collectFlow(mView, mHubToLockscreenTransitionViewModel.getStatusBarAlpha(), - mFromGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher); + if (!Flags.glanceableHubV2()) { + collectFlow(mView, mCommunalSceneInteractor.isCommunalVisible(), mCommunalConsumer, + mCoroutineDispatcher); + collectFlow(mView, mLockscreenToHubTransitionViewModel.getStatusBarAlpha(), + mToGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher); + collectFlow(mView, mHubToLockscreenTransitionViewModel.getStatusBarAlpha(), + mFromGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher); + } if (NewStatusBarIcons.isEnabled()) { ComposeView batteryComposeView = new ComposeView(mContext); UnifiedBatteryViewBinder.bind( @@ -645,7 +648,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat && !mDozing && !hideForBypass && !mDisableStateTracker.isDisabled() - && (!mCommunalShowing || mExplicitAlpha != -1) + && (Flags.glanceableHubV2() || (!mCommunalShowing || mExplicitAlpha != -1)) ? View.VISIBLE : View.INVISIBLE; updateViewState(newAlpha, newVisibility); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 74a42ef3ff7d..f3d72027238f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -29,6 +29,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.IntDef; +import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.util.Log; @@ -226,6 +227,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump private ScrimState mState = ScrimState.UNINITIALIZED; + private Context mContext; + private ScrimView mScrimInFront; private ScrimView mNotificationsScrim; private ScrimView mScrimBehind; @@ -365,7 +368,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump @Main CoroutineDispatcher mainDispatcher, LargeScreenShadeInterpolator largeScreenShadeInterpolator, BlurConfig blurConfig, + @Main Context context, Lazy<WindowRootViewBlurInteractor> windowRootViewBlurInteractor) { + mContext = context; mScrimStateListener = lightBarController::setScrimState; mLargeScreenShadeInterpolator = largeScreenShadeInterpolator; mBlurConfig = blurConfig; @@ -1627,16 +1632,16 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump private void updateThemeColors() { if (mScrimBehind == null) return; - int background = mScrimBehind.getContext().getColor( + int background = mContext.getColor( com.android.internal.R.color.materialColorSurfaceDim); - int accent = mScrimBehind.getContext().getColor( + int accent = mContext.getColor( com.android.internal.R.color.materialColorPrimary); mColors.setMainColor(background); mColors.setSecondaryColor(accent); final boolean isBackgroundLight = !ContrastColorUtil.isColorDark(background); mColors.setSupportsDarkText(isBackgroundLight); - int surface = mScrimBehind.getContext().getColor( + int surface = mContext.getColor( com.android.internal.R.color.materialColorSurface); for (ScrimState state : ScrimState.values()) { state.setSurfaceColor(surface); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java index 05a46cd9fa31..8389aab4aac8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java @@ -219,7 +219,7 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, if (NotificationBundleUi.isEnabled()) { mGroupExpansionManager.toggleGroupExpansion(row.getEntryAdapter()); } else { - mGroupExpansionManager.toggleGroupExpansion(row.getEntry()); + mGroupExpansionManager.toggleGroupExpansion(row.getEntryLegacy()); } } else if (!row.isChildInGroup()) { final boolean expandNotification; @@ -241,7 +241,7 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks, if (NotificationBundleUi.isEnabled()) { mGroupExpansionManager.toggleGroupExpansion(row.getEntryAdapter()); } else { - mGroupExpansionManager.toggleGroupExpansion(row.getEntry()); + mGroupExpansionManager.toggleGroupExpansion(row.getEntryLegacy()); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt index 1a8ca9577bd7..f4afc248d11a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt @@ -22,6 +22,7 @@ import com.android.systemui.KairosBuilder import com.android.systemui.kairos.BuildSpec import com.android.systemui.kairos.ExperimentalKairosApi import com.android.systemui.kairos.State +import com.android.systemui.kairos.combine import com.android.systemui.kairos.flatMap import com.android.systemui.kairosBuilder import com.android.systemui.log.table.TableLogBuffer @@ -55,9 +56,15 @@ constructor( @Assisted private val isCarrierMerged: State<Boolean>, ) : MobileConnectionRepositoryKairos, KairosBuilder by kairosBuilder() { + private var dumpCache: DumpCache? = null + init { onActivated { logDiffsForTable(isCarrierMerged, tableLogBuffer, columnName = "isCarrierMerged") + combine(isCarrierMerged, activeRepo) { isCarrierMerged, activeRepo -> + DumpCache(isCarrierMerged, activeRepo) + } + .observe { dumpCache = it } } } @@ -198,13 +205,6 @@ constructor( override val isInEcmMode: State<Boolean> = activeRepo.flatMap { it.isInEcmMode } - private var dumpCache: DumpCache? = null - - private data class DumpCache( - val isCarrierMerged: Boolean, - val activeRepo: MobileConnectionRepositoryKairos, - ) - fun dump(pw: PrintWriter) { val cache = dumpCache ?: return val ipw = IndentingPrintWriter(pw, " ") @@ -227,6 +227,11 @@ constructor( ipw.decreaseIndent() } + private data class DumpCache( + val isCarrierMerged: Boolean, + val activeRepo: MobileConnectionRepositoryKairos, + ) + @AssistedFactory interface Factory { fun create( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt index e46815954e64..e6c29214e3d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt @@ -131,6 +131,8 @@ constructor( private val mobileRepoFactory: Lazy<ConnectionRepoFactory>, ) : MobileConnectionsRepositoryKairos, Dumpable, KairosBuilder by kairosBuilder() { + private var dumpCache: DumpCache? = null + init { dumpManager.registerNormalDumpable("MobileConnectionsRepositoryKairos", this) } @@ -253,6 +255,7 @@ constructor( .asIncremental() .mapValues { (subId, sub) -> mobileRepoFactory.get().create(subId) } .applyLatestSpecForKey() + .apply { observe { dumpCache = DumpCache(it) } } } private val telephonyManagerState: State<Pair<Int?, Set<Int>>> = buildState { @@ -479,10 +482,6 @@ constructor( profileClass = profileClass, ) - private var dumpCache: DumpCache? = null - - private data class DumpCache(val repos: Map<Int, FullMobileConnectionRepositoryKairos>) - override fun dump(pw: PrintWriter, args: Array<String>) { val cache = dumpCache ?: return val ipw = IndentingPrintWriter(pw, " ") @@ -494,10 +493,16 @@ constructor( ipw.println("Connections (${cache.repos.size} total):") ipw.increaseIndent() - cache.repos.values.forEach { it.dump(ipw) } + cache.repos.values.forEach { + if (it is FullMobileConnectionRepositoryKairos) { + it.dump(ipw) + } + } ipw.decreaseIndent() } + private data class DumpCache(val repos: Map<Int, MobileConnectionRepositoryKairos>) + fun interface ConnectionRepoFactory { fun create(subId: Int): BuildSpec<MobileConnectionRepositoryKairos> } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt index ba666512af5a..2f9cff46d687 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt @@ -196,9 +196,8 @@ fun StatusBarRoot( setContent { PlatformTheme { - val chipsVisibilityModel by + val chipsVisibilityModel = statusBarViewModel.ongoingActivityChips - .collectAsStateWithLifecycle() if (chipsVisibilityModel.areChipsAllowed) { OngoingActivityChips( chips = chipsVisibilityModel.chips, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt index c717b180575c..540babad5dd1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt @@ -21,6 +21,8 @@ import android.graphics.Rect import android.view.Display import android.view.View import androidx.compose.runtime.getValue +import com.android.app.tracing.FlowTracing.traceEach +import com.android.app.tracing.TrackGroupUtils.trackGroup import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor @@ -130,7 +132,7 @@ interface HomeStatusBarViewModel : Activatable { val primaryOngoingActivityChip: StateFlow<OngoingActivityChipModel> /** All supported activity chips, whether they are currently active or not. */ - val ongoingActivityChips: StateFlow<ChipsVisibilityModel> + val ongoingActivityChips: ChipsVisibilityModel /** * The multiple ongoing activity chips that should be shown on the left-hand side of the status @@ -386,11 +388,9 @@ constructor( } override val isHomeStatusBarAllowed = - isHomeStatusBarAllowedCompat.stateIn( - bgScope, - SharingStarted.WhileSubscribed(), - initialValue = false, - ) + isHomeStatusBarAllowedCompat + .traceEach(trackGroup(TRACK_GROUP, "isHomeStatusBarAllowed"), logcat = true) + .stateIn(bgScope, SharingStarted.WhileSubscribed(), initialValue = false) private val shouldHomeStatusBarBeVisible = combine( @@ -461,24 +461,29 @@ constructor( isHomeStatusBarAllowed && !isSecureCameraActive && !hideStartSideContentForHeadsUp } - override val ongoingActivityChips = + private val chipsVisibilityModel: Flow<ChipsVisibilityModel> = combine(ongoingActivityChipsViewModel.chips, canShowOngoingActivityChips) { chips, canShow -> ChipsVisibilityModel(chips, areChipsAllowed = canShow) } - .stateIn( - bgScope, - SharingStarted.WhileSubscribed(), - initialValue = - ChipsVisibilityModel( - chips = MultipleOngoingActivityChipsModel(), - areChipsAllowed = false, - ), - ) + .traceEach(trackGroup(TRACK_GROUP, "chips"), logcat = true) { + "Chips[allowed=${it.areChipsAllowed} numChips=${it.chips.active.size}]" + } + + override val ongoingActivityChips: ChipsVisibilityModel by + hydrator.hydratedStateOf( + traceName = "ongoingActivityChips", + initialValue = + ChipsVisibilityModel( + chips = MultipleOngoingActivityChipsModel(), + areChipsAllowed = false, + ), + source = chipsVisibilityModel, + ) private val hasOngoingActivityChips = if (StatusBarChipsModernization.isEnabled) { - ongoingActivityChips.map { it.chips.active.any { chip -> !chip.isHidden } } + chipsVisibilityModel.map { it.chips.active.any { chip -> !chip.isHidden } } } else if (StatusBarNotifChips.isEnabled) { ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active } } else { @@ -607,6 +612,8 @@ constructor( private const val COL_PREFIX_NOTIF_CONTAINER = "notifContainer" private const val COL_PREFIX_SYSTEM_INFO = "systemInfo" + private const val TRACK_GROUP = "StatusBar" + fun tableLogBufferName(displayId: Int) = "HomeStatusBarViewModel[$displayId]" } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt index a352982f58f2..f6e0123be446 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt @@ -36,20 +36,25 @@ import com.android.systemui.qs.tiles.ModesDndTile import com.android.systemui.qs.tiles.ModesTile import com.android.systemui.qs.tiles.UiModeNightTile import com.android.systemui.qs.tiles.WorkModeTile -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.impl.alarm.domain.AlarmTileMapper +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileDataInteractor import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileUserActionInteractor import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel -import com.android.systemui.qs.tiles.impl.flashlight.domain.FlashlightMapper +import com.android.systemui.qs.tiles.impl.alarm.ui.mapper.AlarmTileMapper import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileDataInteractor import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileUserActionInteractor import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel -import com.android.systemui.qs.tiles.impl.location.domain.LocationTileMapper +import com.android.systemui.qs.tiles.impl.flashlight.ui.mapper.FlashlightMapper import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel +import com.android.systemui.qs.tiles.impl.location.ui.mapper.LocationTileMapper import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor @@ -57,25 +62,20 @@ import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserA import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper -import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper -import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor -import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor +import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper +import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor.SensorPrivacyToggleTileDataInteractor +import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor.SensorPrivacyToggleTileUserActionInteractor import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel -import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources -import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyToggleTileMapper -import com.android.systemui.qs.tiles.impl.uimodenight.domain.UiModeNightTileMapper +import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper.SensorPrivacyToggleTileMapper +import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor -import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel +import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel +import com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper.UiModeNightTileMapper import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileDataInteractor import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileUserActionInteractor import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel -import com.android.systemui.qs.tiles.impl.work.ui.WorkModeTileMapper -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel +import com.android.systemui.qs.tiles.impl.work.ui.mapper.WorkModeTileMapper import com.android.systemui.res.R import dagger.Binds import dagger.Module diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index f1f2b88e9943..6509a698854d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -79,6 +79,7 @@ import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ContrastColorUtil; import com.android.systemui.Dependency; +import com.android.systemui.Flags; import com.android.systemui.res.R; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -245,7 +246,9 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mProgressBar.setProgressTintList(accentColor); mProgressBar.setIndeterminateTintList(accentColor); mProgressBar.setSecondaryProgressTintList(accentColor); - setBackgroundColor(backgroundColor); + if (!Flags.notificationRowTransparency()) { + setBackgroundColor(backgroundColor); + } } @Override @@ -419,10 +422,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene // case to prevent flicker. if (!mRemoved) { ViewGroup parent = (ViewGroup) getParent(); + View actionsContainer = getActionsContainerLayout(); if (animate && parent != null) { ViewGroup grandParent = (ViewGroup) parent.getParent(); - View actionsContainer = getActionsContainerLayout(); int actionsContainerHeight = actionsContainer != null ? actionsContainer.getHeight() : 0; @@ -459,6 +462,9 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene if (mWrapper != null) { mWrapper.setRemoteInputVisible(false); } + if (Flags.notificationRowTransparency()) { + if (actionsContainer != null) actionsContainer.setAlpha(1); + } } } unregisterBackCallback(); @@ -823,12 +829,14 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene ObjectAnimator.ofFloat(fadeOutView, View.ALPHA, 1f, 0f); fadeOutViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION); fadeOutViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR); - animatorSet.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation, boolean isReverse) { - fadeOutView.setAlpha(1f); - } - }); + if (!Flags.notificationRowTransparency()) { + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation, boolean isReverse) { + fadeOutView.setAlpha(1f); + } + }); + } animatorSet.playTogether(alphaAnimator, scaleAnimator, fadeOutViewAlphaAnimator); } return animatorSet; diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index 48d7747d2dc2..bd3feadf4459 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -988,6 +988,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable { public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { pw.println("mSystemColors=" + mCurrentColors); pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor)); + pw.println("mContrast=" + mContrast); pw.println("mSecondaryOverlay=" + mSecondaryOverlay); pw.println("mNeutralOverlay=" + mNeutralOverlay); pw.println("mDynamicOverlay=" + mDynamicOverlay); diff --git a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt index 47e27bc59f96..1cc7a3185a5d 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt @@ -50,6 +50,7 @@ class DisplaySwitchLatencyLogger { onScreenTurningOnToOnDrawnMs, onDrawnToOnScreenTurnedOnMs, trackingResult, + screenWakelockstatus ) } } diff --git a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt index 66de52260b79..5800d5ed41c6 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt @@ -344,6 +344,8 @@ constructor( val onDrawnToOnScreenTurnedOnMs: Int = VALUE_UNKNOWN, val trackingResult: Int = SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__UNKNOWN_RESULT, + val screenWakelockstatus: Int = + SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__SCREEN_WAKELOCK_STATUS__SCREEN_WAKELOCK_STATUS_UNKNOWN, ) enum class TrackingResult { diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt index 05b2e0d1423e..b33eafcdfa84 100644 --- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt @@ -414,16 +414,15 @@ constructor( } } + private suspend fun SelectedUserModel.isEligibleForLogout(): Boolean { + return withContext(backgroundDispatcher) { + selectionStatus == SelectionStatus.SELECTION_COMPLETE && + devicePolicyManager.logoutUser != null + } + } + companion object { private const val TAG = "UserRepository" @VisibleForTesting const val SETTING_SIMPLE_USER_SWITCHER = "lockscreenSimpleUserSwitcher" } } - -fun SelectedUserModel.isEligibleForLogout(): Boolean { - // TODO(b/206032495): should call mDevicePolicyManager.getLogoutUserId() instead of - // hardcode it to USER_SYSTEM so it properly supports headless system user mode - // (and then call mDevicePolicyManager.clearLogoutUser() after switched) - return selectionStatus == SelectionStatus.SELECTION_COMPLETE && - userInfo.id != android.os.UserHandle.USER_SYSTEM -} diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt index 735da46667c5..cc4307a67268 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt @@ -19,8 +19,11 @@ package com.android.systemui.util.kotlin import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.util.time.SystemClock import com.android.systemui.util.time.SystemClockImpl +import java.util.LinkedList import java.util.concurrent.atomic.AtomicReference import kotlin.math.max +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -364,3 +367,58 @@ inline fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> combine( */ @Suppress("NOTHING_TO_INLINE") inline fun Flow<Unit>.emitOnStart(): Flow<Unit> = onStart { emit(Unit) } + +/** + * Transforms a Flow<T> into a Flow<List<T>> by implementing a sliding window algorithm. + * + * This function creates a sliding window over the input Flow<T>. The window has a specified + * [windowDuration] and slides continuously as time progresses. The emitted List<T> contains all + * items from the input flow that fall within the current window. + * + * The window slides forward by the smallest possible increment to include or exclude *one* event + * based on the time the event was emitted (determined by the System.currentTimeMillis()). This + * means that consecutive emitted lists will have overlapping elements if the elements fall within + * the [windowDuration] + * + * @param windowDuration The duration of the sliding window. + * @return A Flow that emits Lists of elements within the current sliding window. + */ +fun <T> Flow<T>.slidingWindow( + windowDuration: Duration, + clock: SystemClock = SystemClockImpl(), +): Flow<List<T>> = channelFlow { + require(windowDuration.isPositive()) { "Window duration must be positive" } + val buffer = LinkedList<Pair<Duration, T>>() + + coroutineScope { + var windowAdvancementJob: Job? = null + + collect { value -> + windowAdvancementJob?.cancel() + val now = clock.currentTimeMillis().milliseconds + buffer.addLast(now to value) + + while (buffer.isNotEmpty() && buffer.first.first + windowDuration <= now) { + buffer.removeFirst() + } + send(buffer.map { it.second }) + + // Keep the window advancing through time even if the source flow isn't emitting + // anymore. We stop advancing the window as soon as there are no items left in the + // buffer. + windowAdvancementJob = launch { + while (buffer.isNotEmpty()) { + val startOfWindow = clock.currentTimeMillis().milliseconds - windowDuration + // Invariant: At this point, everything in the buffer is guaranteed to be in + // the window, as we removed expired items above. + val timeUntilNextOldest = + (buffer.first.first - startOfWindow).coerceAtLeast(0.milliseconds) + delay(timeUntilNextOldest) + // Remove the oldest item, as it has now fallen out of the window. + buffer.removeFirst() + send(buffer.map { it.second }) + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt index 1f11f2da8340..f6aa189eb571 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt @@ -40,7 +40,6 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest @@ -78,11 +77,16 @@ constructor( private val userVolumeUpdates = MutableStateFlow<VolumeUpdate?>(null) private val model: Flow<VolumeDialogStreamModel> = - interactor.slider - .filter { - val currentVolumeUpdate = userVolumeUpdates.value ?: return@filter true + combine(interactor.slider, userVolumeUpdates) { model, currentVolumeUpdate -> + currentVolumeUpdate ?: return@combine model val lastVolumeUpdateTime = currentVolumeUpdate.timestampMillis - getTimestampMillis() - lastVolumeUpdateTime > VOLUME_UPDATE_GRACE_PERIOD + val shouldIgnoreUpdates = + getTimestampMillis() - lastVolumeUpdateTime < VOLUME_UPDATE_GRACE_PERIOD + if (shouldIgnoreUpdates) { + model.copy(level = currentVolumeUpdate.newVolumeLevel) + } else { + model + } } .stateIn(coroutineScope, SharingStarted.Eagerly, null) .filterNotNull() diff --git a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java index dd1c11d11d1e..e9180df0806b 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java @@ -28,9 +28,9 @@ import com.android.systemui.qs.pipeline.shared.TileSpec; import com.android.systemui.qs.shared.model.TileCategory; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.qs.tiles.QuickAccessWalletTile; -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig; -import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy; -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig; +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig; +import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy; +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig; import com.android.systemui.res.R; import com.android.systemui.wallet.controller.WalletContextualLocationsService; import com.android.systemui.wallet.ui.WalletActivity; diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.java deleted file mode 100644 index 7297e0f3bff5..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2024 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.lowlightclock; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; - -import android.testing.AndroidTestingRunner; - -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.shared.condition.Condition; -import com.android.systemui.statusbar.commandline.Command; -import com.android.systemui.statusbar.commandline.CommandRegistry; - -import kotlin.jvm.functions.Function0; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.io.PrintWriter; -import java.util.Arrays; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -public class ForceLowLightConditionTest extends SysuiTestCase { - @Mock - private CommandRegistry mCommandRegistry; - - @Mock - private Condition.Callback mCallback; - - @Mock - private PrintWriter mPrintWriter; - - @Mock - CoroutineScope mScope; - - private ForceLowLightCondition mCondition; - private Command mCommand; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mCondition = new ForceLowLightCondition(mScope, mCommandRegistry); - mCondition.addCallback(mCallback); - ArgumentCaptor<Function0<Command>> commandCaptor = - ArgumentCaptor.forClass(Function0.class); - verify(mCommandRegistry).registerCommand(eq(ForceLowLightCondition.COMMAND_ROOT), - commandCaptor.capture()); - mCommand = commandCaptor.getValue().invoke(); - } - - @Test - public void testEnableLowLight() { - mCommand.execute(mPrintWriter, - Arrays.asList(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT)); - verify(mCallback).onConditionChanged(mCondition); - assertThat(mCondition.isConditionSet()).isTrue(); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void testDisableLowLight() { - mCommand.execute(mPrintWriter, - Arrays.asList(ForceLowLightCondition.COMMAND_DISABLE_LOW_LIGHT)); - verify(mCallback).onConditionChanged(mCondition); - assertThat(mCondition.isConditionSet()).isTrue(); - assertThat(mCondition.isConditionMet()).isFalse(); - } - - @Test - public void testClearEnableLowLight() { - mCommand.execute(mPrintWriter, - Arrays.asList(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT)); - verify(mCallback).onConditionChanged(mCondition); - assertThat(mCondition.isConditionSet()).isTrue(); - assertThat(mCondition.isConditionMet()).isTrue(); - Mockito.clearInvocations(mCallback); - mCommand.execute(mPrintWriter, - Arrays.asList(ForceLowLightCondition.COMMAND_CLEAR_LOW_LIGHT)); - verify(mCallback).onConditionChanged(mCondition); - assertThat(mCondition.isConditionSet()).isFalse(); - assertThat(mCondition.isConditionMet()).isFalse(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.kt new file mode 100644 index 000000000000..f8ce242c39d2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.kt @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2025 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.lowlightclock + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.shared.condition.Condition +import com.android.systemui.statusbar.commandline.Command +import com.android.systemui.statusbar.commandline.CommandRegistry +import com.google.common.truth.Truth +import java.io.PrintWriter +import java.util.Arrays +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class ForceLowLightConditionTest : SysuiTestCase() { + private val kosmos = Kosmos() + + @Mock private lateinit var commandRegistry: CommandRegistry + + @Mock private lateinit var callback: Condition.Callback + + @Mock private lateinit var printWriter: PrintWriter + + private lateinit var condition: ForceLowLightCondition + private lateinit var command: Command + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + condition = ForceLowLightCondition(kosmos.testScope, commandRegistry) + condition.addCallback(callback) + val commandCaptor = argumentCaptor<() -> Command>() + Mockito.verify(commandRegistry) + .registerCommand(eq(ForceLowLightCondition.COMMAND_ROOT), commandCaptor.capture()) + command = commandCaptor.lastValue.invoke() + } + + @Test + fun testEnableLowLight() = + kosmos.runTest { + command.execute( + printWriter, + Arrays.asList(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT), + ) + Mockito.verify(callback).onConditionChanged(condition) + Truth.assertThat(condition.isConditionSet).isTrue() + Truth.assertThat(condition.isConditionMet).isTrue() + } + + @Test + fun testDisableLowLight() = + kosmos.runTest { + command.execute(printWriter, listOf(ForceLowLightCondition.COMMAND_DISABLE_LOW_LIGHT)) + Mockito.verify(callback).onConditionChanged(condition) + Truth.assertThat(condition.isConditionSet).isTrue() + Truth.assertThat(condition.isConditionMet).isFalse() + } + + @Test + fun testClearEnableLowLight() = + kosmos.runTest { + command.execute(printWriter, listOf(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT)) + Mockito.verify(callback).onConditionChanged(condition) + Truth.assertThat(condition.isConditionSet).isTrue() + Truth.assertThat(condition.isConditionMet).isTrue() + Mockito.clearInvocations(callback) + command.execute(printWriter, listOf(ForceLowLightCondition.COMMAND_CLEAR_LOW_LIGHT)) + Mockito.verify(callback).onConditionChanged(condition) + Truth.assertThat(condition.isConditionSet).isFalse() + Truth.assertThat(condition.isConditionMet).isFalse() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.java deleted file mode 100644 index 2c216244985e..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2024 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.lowlightclock; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.testing.AndroidTestingRunner; - -import androidx.test.filters.SmallTest; - -import com.android.internal.logging.UiEventLogger; -import com.android.systemui.SysuiTestCase; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -public class LowLightConditionTest extends SysuiTestCase { - @Mock - private AmbientLightModeMonitor mAmbientLightModeMonitor; - @Mock - private UiEventLogger mUiEventLogger; - @Mock - CoroutineScope mScope; - private LowLightCondition mCondition; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mCondition = new LowLightCondition(mScope, mAmbientLightModeMonitor, mUiEventLogger); - mCondition.start(); - } - - @Test - public void testLowLightFalse() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT); - assertThat(mCondition.isConditionMet()).isFalse(); - } - - @Test - public void testLowLightTrue() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void testUndecidedLowLightStateIgnored() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - assertThat(mCondition.isConditionMet()).isTrue(); - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void testLowLightChange() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT); - assertThat(mCondition.isConditionMet()).isFalse(); - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void testResetIsConditionMetUponStop() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - assertThat(mCondition.isConditionMet()).isTrue(); - - mCondition.stop(); - assertThat(mCondition.isConditionMet()).isFalse(); - } - - @Test - public void testLoggingAmbientLightNotLowToLow() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - // Only logged once. - verify(mUiEventLogger, times(1)).log(any()); - // Logged with the correct state. - verify(mUiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_DARK); - } - - @Test - public void testLoggingAmbientLightLowToLow() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - reset(mUiEventLogger); - - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - // Doesn't log. - verify(mUiEventLogger, never()).log(any()); - } - - @Test - public void testLoggingAmbientLightNotLowToNotLow() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT); - // Doesn't log. - verify(mUiEventLogger, never()).log(any()); - } - - @Test - public void testLoggingAmbientLightLowToNotLow() { - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK); - reset(mUiEventLogger); - - changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT); - // Only logged once. - verify(mUiEventLogger).log(any()); - // Logged with the correct state. - verify(mUiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT); - } - - private void changeLowLightMode(int mode) { - ArgumentCaptor<AmbientLightModeMonitor.Callback> ambientLightCallbackCaptor = - ArgumentCaptor.forClass(AmbientLightModeMonitor.Callback.class); - verify(mAmbientLightModeMonitor).start(ambientLightCallbackCaptor.capture()); - ambientLightCallbackCaptor.getValue().onChange(mode); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.kt new file mode 100644 index 000000000000..da68442a70cc --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.kt @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2025 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.lowlightclock + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.internal.logging.UiEventLogger +import com.android.systemui.SysuiTestCase +import com.android.systemui.condition.testStart +import com.android.systemui.condition.testStop +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.argumentCaptor + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class LowLightConditionTest : SysuiTestCase() { + private val kosmos = testKosmos() + + @Mock private lateinit var ambientLightModeMonitor: AmbientLightModeMonitor + + @Mock private lateinit var uiEventLogger: UiEventLogger + + private lateinit var condition: LowLightCondition + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + condition = LowLightCondition(kosmos.testScope, ambientLightModeMonitor, uiEventLogger) + } + + @Test + fun testLowLightFalse() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT) + Truth.assertThat(condition.isConditionMet).isFalse() + } + + @Test + fun testLowLightTrue() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + Truth.assertThat(condition.isConditionMet).isTrue() + } + + @Test + fun testUndecidedLowLightStateIgnored() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + Truth.assertThat(condition.isConditionMet).isTrue() + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED) + Truth.assertThat(condition.isConditionMet).isTrue() + } + + @Test + fun testLowLightChange() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT) + Truth.assertThat(condition.isConditionMet).isFalse() + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + Truth.assertThat(condition.isConditionMet).isTrue() + } + + @Test + fun testResetIsConditionMetUponStop() = + kosmos.runTest { + testStart(condition) + runCurrent() + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + Truth.assertThat(condition.isConditionMet).isTrue() + + testStop(condition) + Truth.assertThat(condition.isConditionMet).isFalse() + } + + @Test + fun testLoggingAmbientLightNotLowToLow() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + // Only logged once. + Mockito.verify(uiEventLogger, Mockito.times(1)).log(ArgumentMatchers.any()) + // Logged with the correct state. + Mockito.verify(uiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_DARK) + } + + @Test + fun testLoggingAmbientLightLowToLow() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + Mockito.reset(uiEventLogger) + + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + // Doesn't log. + Mockito.verify(uiEventLogger, Mockito.never()).log(ArgumentMatchers.any()) + } + + @Test + fun testLoggingAmbientLightNotLowToNotLow() = + kosmos.runTest { + testStart(condition) + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT) + // Doesn't log. + Mockito.verify(uiEventLogger, Mockito.never()).log(ArgumentMatchers.any()) + } + + @Test + fun testLoggingAmbientLightLowToNotLow() = + kosmos.runTest { + testStart(condition) + runCurrent() + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK) + Mockito.reset(uiEventLogger) + + changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT) + // Only logged once. + Mockito.verify(uiEventLogger).log(ArgumentMatchers.any()) + // Logged with the correct state. + Mockito.verify(uiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT) + } + + private fun changeLowLightMode(mode: Int) { + val ambientLightCallbackCaptor = argumentCaptor<AmbientLightModeMonitor.Callback>() + + Mockito.verify(ambientLightModeMonitor).start(ambientLightCallbackCaptor.capture()) + ambientLightCallbackCaptor.lastValue.onChange(mode) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.java deleted file mode 100644 index 366c071fb93f..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2024 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.lowlightclock; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.res.Resources; -import android.database.ContentObserver; -import android.os.UserHandle; -import android.provider.Settings; -import android.testing.AndroidTestingRunner; - -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.util.settings.SecureSettings; - -import kotlinx.coroutines.CoroutineScope; - -import org.junit.Before; -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; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -public class ScreenSaverEnabledConditionTest extends SysuiTestCase { - @Mock - private Resources mResources; - @Mock - private SecureSettings mSecureSettings; - @Mock - CoroutineScope mScope; - @Captor - private ArgumentCaptor<ContentObserver> mSettingsObserverCaptor; - private ScreenSaverEnabledCondition mCondition; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - // Default dreams to enabled by default - doReturn(true).when(mResources).getBoolean( - com.android.internal.R.bool.config_dreamsEnabledByDefault); - - mCondition = new ScreenSaverEnabledCondition(mScope, mResources, mSecureSettings); - } - - @Test - public void testScreenSaverInitiallyEnabled() { - setScreenSaverEnabled(true); - mCondition.start(); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - @Test - public void testScreenSaverInitiallyDisabled() { - setScreenSaverEnabled(false); - mCondition.start(); - assertThat(mCondition.isConditionMet()).isFalse(); - } - - @Test - public void testScreenSaverStateChanges() { - setScreenSaverEnabled(false); - mCondition.start(); - assertThat(mCondition.isConditionMet()).isFalse(); - - setScreenSaverEnabled(true); - final ContentObserver observer = captureSettingsObserver(); - observer.onChange(/* selfChange= */ false); - assertThat(mCondition.isConditionMet()).isTrue(); - } - - private void setScreenSaverEnabled(boolean enabled) { - when(mSecureSettings.getIntForUser(eq(Settings.Secure.SCREENSAVER_ENABLED), anyInt(), - eq(UserHandle.USER_CURRENT))).thenReturn(enabled ? 1 : 0); - } - - private ContentObserver captureSettingsObserver() { - verify(mSecureSettings).registerContentObserverForUserSync( - eq(Settings.Secure.SCREENSAVER_ENABLED), - mSettingsObserverCaptor.capture(), eq(UserHandle.USER_CURRENT)); - return mSettingsObserverCaptor.getValue(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.kt new file mode 100644 index 000000000000..29237a71d085 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.kt @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2025 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.lowlightclock + +import android.content.res.Resources +import android.database.ContentObserver +import android.os.UserHandle +import android.provider.Settings +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.internal.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.condition.testStart +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.kosmos.runTest +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.android.systemui.util.settings.SecureSettings +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class ScreenSaverEnabledConditionTest : SysuiTestCase() { + private val kosmos = testKosmos() + + @Mock private lateinit var resources: Resources + + @Mock private lateinit var secureSettings: SecureSettings + + private val settingsObserverCaptor = argumentCaptor<ContentObserver>() + private lateinit var condition: ScreenSaverEnabledCondition + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + // Default dreams to enabled by default + whenever(resources.getBoolean(R.bool.config_dreamsEnabledByDefault)).thenReturn(true) + + condition = ScreenSaverEnabledCondition(kosmos.testScope, resources, secureSettings) + } + + @Test + fun testScreenSaverInitiallyEnabled() = + kosmos.runTest { + setScreenSaverEnabled(true) + testStart(condition) + Truth.assertThat(condition.isConditionMet).isTrue() + } + + @Test + fun testScreenSaverInitiallyDisabled() = + kosmos.runTest { + setScreenSaverEnabled(false) + testStart(condition) + Truth.assertThat(condition.isConditionMet).isFalse() + } + + @Test + fun testScreenSaverStateChanges() = + kosmos.runTest { + setScreenSaverEnabled(false) + testStart(condition) + Truth.assertThat(condition.isConditionMet).isFalse() + + setScreenSaverEnabled(true) + runCurrent() + val observer = captureSettingsObserver() + observer.onChange(/* selfChange= */ false) + Truth.assertThat(condition.isConditionMet).isTrue() + } + + private fun setScreenSaverEnabled(enabled: Boolean) { + whenever( + secureSettings.getIntForUser( + eq(Settings.Secure.SCREENSAVER_ENABLED), + any(), + eq(UserHandle.USER_CURRENT), + ) + ) + .thenReturn(if (enabled) 1 else 0) + } + + private fun captureSettingsObserver(): ContentObserver { + Mockito.verify(secureSettings) + .registerContentObserverForUserSync( + eq(Settings.Secure.SCREENSAVER_ENABLED), + settingsObserverCaptor.capture(), + eq(UserHandle.USER_CURRENT), + ) + return settingsObserverCaptor.lastValue + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt index cf54df8565d3..997cf417fe10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt @@ -22,6 +22,7 @@ import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.view.Display import androidx.test.filters.SmallTest +import com.android.keyguard.keyguardUpdateMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.deviceStateManager import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor @@ -37,6 +38,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import org.junit.Before import org.junit.Test +import org.mockito.Mockito.times import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.never @@ -59,6 +61,7 @@ class RearDisplayCoreStartableTest : SysuiTestCase() { fakeRearDisplayStateInteractor, kosmos.rearDisplayInnerDialogDelegateFactory, kosmos.testScope, + kosmos.keyguardUpdateMonitor, ) @Before @@ -96,6 +99,26 @@ class RearDisplayCoreStartableTest : SysuiTestCase() { } } + @Test + @EnableFlags(FLAG_DEVICE_STATE_RDM_V2) + fun testDialogResumesAfterKeyguardGone() = + kosmos.runTest { + impl.use { + it.start() + fakeRearDisplayStateInteractor.emitRearDisplay() + + verify(mockDialog).show() + + it.keyguardCallback.onKeyguardVisibilityChanged(true) + // Do not need to check that the dialog is dismissed, since SystemUIDialog + // implementation handles that. We just toggle keyguard here so that the flow + // emits. + + it.keyguardCallback.onKeyguardVisibilityChanged(false) + verify(mockDialog, times(2)).show() + } + } + private class FakeRearDisplayStateInteractor(private val kosmos: Kosmos) : RearDisplayStateInteractor { private val stateFlow = MutableSharedFlow<RearDisplayStateInteractor.State>() diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt index e0118b18ff64..9b03833fd1b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt @@ -22,6 +22,7 @@ import android.content.pm.PackageManager import android.content.pm.ResolveInfo import android.os.PowerManager import android.os.UserManager +import android.platform.test.annotations.EnableFlags import android.testing.TestableContext import android.testing.TestableLooper import android.view.Display @@ -29,17 +30,23 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.app.AssistUtils import com.android.internal.logging.UiEventLogger +import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager +import com.android.systemui.kosmos.testScope import com.android.systemui.log.assertLogsWtf +import com.android.systemui.model.fakeSysUIStatePerDisplayRepository import com.android.systemui.model.sysUiState +import com.android.systemui.model.sysUiStateFactory import com.android.systemui.navigationbar.NavigationBarController import com.android.systemui.navigationbar.NavigationModeController +import com.android.systemui.navigationbar.views.NavigationBar import com.android.systemui.process.ProcessWrapper import com.android.systemui.recents.LauncherProxyService.ACTION_QUICKSTEP import com.android.systemui.settings.FakeDisplayTracker @@ -56,18 +63,20 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.testKosmos import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.android.wm.shell.back.BackAnimation import com.android.wm.shell.sysui.ShellInterface import com.google.common.util.concurrent.MoreExecutors import java.util.Optional import java.util.concurrent.Executor +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers +import org.mockito.ArgumentMatchers.anyLong import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.any @@ -81,6 +90,7 @@ import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations +import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) @@ -96,8 +106,10 @@ class LauncherProxyServiceTest : SysuiTestCase() { private val displayTracker = FakeDisplayTracker(mContext) private val fakeSystemClock = FakeSystemClock() private val sysUiState = kosmos.sysUiState + private val sysUiStateFactory = kosmos.sysUiStateFactory private val wakefulnessLifecycle = WakefulnessLifecycle(mContext, null, fakeSystemClock, dumpManager) + private val sysuiStatePerDisplayRepository = kosmos.fakeSysUIStatePerDisplayRepository @Mock private lateinit var launcherProxy: ILauncherProxy.Stub @Mock private lateinit var packageManager: PackageManager @@ -149,6 +161,8 @@ class LauncherProxyServiceTest : SysuiTestCase() { // return isSystemUser as true by default. `when`(processWrapper.isSystemUser).thenReturn(true) + sysuiStatePerDisplayRepository.add(Display.DEFAULT_DISPLAY, sysUiState) + runBlocking { kosmos.displayRepository.apply { addDisplay(0) } } subject = createLauncherProxyService(context) } @@ -249,6 +263,48 @@ class LauncherProxyServiceTest : SysuiTestCase() { verify(spyContext, times(0)).bindServiceAsUser(any(), any(), anyInt(), any()) } + @Test + fun notifySysUiStateFlagsForAllDisplays_triggersUpdateInAllDisplays() = + kosmos.testScope.runTest { + kosmos.displayRepository.apply { + addDisplay(0) + addDisplay(1) + addDisplay(2) + } + kosmos.fakeSysUIStatePerDisplayRepository.apply { + add(1, sysUiStateFactory.create(1)) + add(2, sysUiStateFactory.create(2)) + } + clearInvocations(launcherProxy) + subject.notifySysUiStateFlagsForAllDisplays() + + verify(launcherProxy).onSystemUiStateChanged(anyLong(), eq(0)) + verify(launcherProxy).onSystemUiStateChanged(anyLong(), eq(1)) + verify(launcherProxy).onSystemUiStateChanged(anyLong(), eq(2)) + } + + @Test + @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND) + fun updateSystemUiStateFlags_updatesAllNavBars() = + kosmos.testScope.runTest { + kosmos.displayRepository.apply { + addDisplay(0) + addDisplay(1) + } + kosmos.fakeSysUIStatePerDisplayRepository.apply { + add(1, sysUiStateFactory.create(1)) + } + val navBar0 = mock<NavigationBar>() + val navBar1 = mock<NavigationBar>() + whenever(navBarController.getNavigationBar(eq(0))).thenReturn(navBar0) + whenever(navBarController.getNavigationBar(eq(1))).thenReturn(navBar1) + + subject.updateSystemUiStateFlags() + + verify(navBar0).updateSystemUiStateFlags() + verify(navBar1).updateSystemUiStateFlags() + } + private fun createLauncherProxyService(ctx: Context): LauncherProxyService { return LauncherProxyService( ctx, @@ -260,7 +316,7 @@ class LauncherProxyServiceTest : SysuiTestCase() { screenPinningRequest, navModeController, statusBarWinController, - sysUiState, + kosmos.fakeSysUIStatePerDisplayRepository, mock(), mock(), userTracker, @@ -276,6 +332,7 @@ class LauncherProxyServiceTest : SysuiTestCase() { broadcastDispatcher, backAnimation, processWrapper, + kosmos.displayRepository, ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt index 116a2caa6dda..e1e9aa3d193e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt @@ -35,8 +35,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class CombinedConditionTest : SysuiTestCase() { - class FakeCondition - constructor( + class FakeCondition( scope: CoroutineScope, initialValue: Boolean?, overriding: Boolean = false, @@ -46,7 +45,7 @@ class CombinedConditionTest : SysuiTestCase() { val started: Boolean get() = _started - override fun start() { + override suspend fun start() { _started = true } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt index 3937d3d46d68..ff17a362eb32 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt @@ -20,7 +20,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener @@ -97,7 +96,6 @@ class ViewConfigCoordinatorTest : SysuiTestCase() { fun themeChangePropagatesToEntry() { configurationListener.onThemeChanged() verify(entry).onDensityOrFontScaleChanged() - checkGutsExposedCalled() verifyNoMoreInteractions(entry, row) } @@ -105,7 +103,6 @@ class ViewConfigCoordinatorTest : SysuiTestCase() { fun densityChangePropagatesToEntry() { configurationListener.onDensityOrFontScaleChanged() verify(entry).onDensityOrFontScaleChanged() - checkGutsExposedCalled() verifyNoMoreInteractions(entry, row) } @@ -129,7 +126,6 @@ class ViewConfigCoordinatorTest : SysuiTestCase() { verify(entry).row verify(row).onUiModeChanged() verify(entry).onDensityOrFontScaleChanged() - checkGutsExposedCalled() verifyNoMoreInteractions(entry, row) clearInvocations(entry, row) @@ -160,7 +156,6 @@ class ViewConfigCoordinatorTest : SysuiTestCase() { verify(entry).row verify(row).onUiModeChanged() verify(entry).onDensityOrFontScaleChanged() - checkGutsExposedCalled() verifyNoMoreInteractions(entry, row) clearInvocations(entry, row) @@ -196,14 +191,7 @@ class ViewConfigCoordinatorTest : SysuiTestCase() { verify(entry).row verify(row).onUiModeChanged() verify(entry).onDensityOrFontScaleChanged() - checkGutsExposedCalled() verifyNoMoreInteractions(entry, row) clearInvocations(entry, row) } - - private fun checkGutsExposedCalled() { - if (!Flags.notificationUndoGutsOnConfigChanged()) { - verify(entry).areGutsExposed() - } - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 00ee893e0e4d..2ea4e7f67b3c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -180,6 +180,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void testUpdateBackgroundColors_isRecursive() throws Exception { ExpandableNotificationRow group = mNotificationTestHelper.createGroup(); group.setTintColor(Color.RED); @@ -604,14 +605,14 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { public void testGetIsNonblockable() throws Exception { ExpandableNotificationRow row = mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); - row.setEntry(null); + row.setEntryLegacy(null); assertTrue(row.getIsNonblockable()); NotificationEntry entry = mock(NotificationEntry.class); Mockito.doReturn(false, true).when(entry).isBlockable(); - row.setEntry(entry); + row.setEntryLegacy(entry); assertTrue(row.getIsNonblockable()); assertFalse(row.getIsNonblockable()); } @@ -946,9 +947,13 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME}) + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void isExpanded_sensitivePromotedNotification_notExpanded() throws Exception { // GIVEN final ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + NotificationEntry entry = mock(NotificationEntry.class); + when(entry.isPromotedOngoing()).thenReturn(true); + row.setEntryLegacy(entry); setRowPromotedOngoing(row); row.setSensitive(/* sensitive= */true, /* hideSensitive= */false); row.setHideSensitiveForIntrinsicHeight(/* hideSensitive= */true); @@ -959,9 +964,13 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME}) + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void isExpanded_promotedNotificationNotOnKeyguard_expanded() throws Exception { // GIVEN final ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + NotificationEntry entry = mock(NotificationEntry.class); + when(entry.isPromotedOngoing()).thenReturn(true); + row.setEntryLegacy(entry); setRowPromotedOngoing(row); row.setOnKeyguard(false); @@ -971,9 +980,13 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME}) + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void isExpanded_promotedNotificationAllowOnKeyguard_expanded() throws Exception { // GIVEN final ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + NotificationEntry entry = mock(NotificationEntry.class); + when(entry.isPromotedOngoing()).thenReturn(true); + row.setEntryLegacy(entry); setRowPromotedOngoing(row); row.setOnKeyguard(true); @@ -983,10 +996,14 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME}) + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void isExpanded_promotedNotificationIgnoreLockscreenConstraints_expanded() throws Exception { // GIVEN final ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + NotificationEntry entry = mock(NotificationEntry.class); + when(entry.isPromotedOngoing()).thenReturn(true); + row.setEntryLegacy(entry); setRowPromotedOngoing(row); row.setOnKeyguard(true); row.setIgnoreLockscreenConstraints(true); @@ -1009,16 +1026,20 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { entry); row.setEntryAdapter(entryAdapter); } else { - row.setEntry(entry); + row.setEntryLegacy(entry); } } @Test @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME}) + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void isExpanded_promotedNotificationSaveSpaceOnLockScreen_notExpanded() throws Exception { // GIVEN final ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + NotificationEntry entry = mock(NotificationEntry.class); + when(entry.isPromotedOngoing()).thenReturn(true); + row.setEntryLegacy(entry); setRowPromotedOngoing(row); row.setOnKeyguard(true); row.setSaveSpaceOnLockscreen(true); @@ -1029,10 +1050,14 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME}) + @DisableFlags(NotificationBundleUi.FLAG_NAME) public void isExpanded_promotedNotificationNotSaveSpaceOnLockScreen_expanded() throws Exception { // GIVEN final ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + NotificationEntry entry = mock(NotificationEntry.class); + when(entry.isPromotedOngoing()).thenReturn(true); + row.setEntryLegacy(entry); setRowPromotedOngoing(row); row.setOnKeyguard(true); row.setSaveSpaceOnLockscreen(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt index c874bc6056c6..82082cc778b6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2025 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. @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.row import android.annotation.DimenRes import android.content.res.Resources import android.os.UserHandle +import android.platform.test.annotations.DisableFlags import android.service.notification.StatusBarNotification import android.testing.TestableLooper import android.testing.ViewUtils @@ -37,9 +38,13 @@ import com.android.internal.widget.NotificationExpandButton import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.FeedbackIcon import com.android.systemui.statusbar.notification.collection.EntryAdapter +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.collection.msgStyleBubbleableFullPerson +import com.android.systemui.statusbar.notification.people.peopleNotificationIdentifier import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier import com.android.systemui.statusbar.notification.shared.NotificationBundleUi +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -50,7 +55,6 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyInt @@ -66,10 +70,12 @@ import org.mockito.MockitoAnnotations.initMocks @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class NotificationContentViewTest : SysuiTestCase() { + private val kosmos = testKosmos() + + private val factory: EntryAdapterFactory = kosmos.entryAdapterFactory private lateinit var row: ExpandableNotificationRow private lateinit var fakeParent: ViewGroup - @Mock private lateinit var mPeopleNotificationIdentifier: PeopleNotificationIdentifier private val testableResources = mContext.getOrCreateTestableResources() private val contractedHeight = @@ -81,25 +87,19 @@ class NotificationContentViewTest : SysuiTestCase() { fun setup() { initMocks(this) fakeParent = - spy(FrameLayout(mContext, /* attrs= */ null).also { it.visibility = View.GONE }) - val mockEntry = createMockNotificationEntry() - val mockEntryAdapter = createMockNotificationEntryAdapter() + spy(FrameLayout(mContext, /* attrs= */ null)).also { it.visibility = View.GONE } + val entry = kosmos.msgStyleBubbleableFullPerson + val mockEntryAdapter = factory.create(entry) row = spy( when (NotificationBundleUi.isEnabled) { true -> { - ExpandableNotificationRow( - mContext, - /* attrs= */ null, - UserHandle.CURRENT - ).apply { - entry = mockEntry - entryAdapter = mockEntryAdapter - } + ExpandableNotificationRow(mContext, /* attrs= */ null, UserHandle.CURRENT) + .apply { entryAdapter = mockEntryAdapter } } false -> { - ExpandableNotificationRow(mContext, /* attrs= */ null, mockEntry).apply { - entry = mockEntry + ExpandableNotificationRow(mContext, /* attrs= */ null, entry).apply { + entryLegacy = entry } } } @@ -402,14 +402,15 @@ class NotificationContentViewTest : SysuiTestCase() { } @Test + @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES) fun setExpandedChild_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() { // Given: bottom margin of actionListMarginTarget is notificationContentMargin // Bubble button should not be shown for the given NotificationEntry - val mockNotificationEntry = createMockNotificationEntry() + val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) val actionListMarginTarget = spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) - val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + val mockExpandedChild = createMockExpandedChild() whenever( mockExpandedChild.findViewById<LinearLayout>( R.id.notification_action_list_margin_target @@ -429,14 +430,15 @@ class NotificationContentViewTest : SysuiTestCase() { } @Test + @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES) fun setExpandedChild_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() { // Given: bottom margin of actionListMarginTarget is notificationContentMargin // Bubble button should be shown for the given NotificationEntry - val mockNotificationEntry = createMockNotificationEntry() + val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) val actionListMarginTarget = spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) - val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + val mockExpandedChild = createMockExpandedChild() whenever( mockExpandedChild.findViewById<LinearLayout>( R.id.notification_action_list_margin_target @@ -458,13 +460,14 @@ class NotificationContentViewTest : SysuiTestCase() { } @Test + @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES) fun onNotificationUpdated_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() { // Given: bottom margin of actionListMarginTarget is notificationContentMargin - val mockNotificationEntry = createMockNotificationEntry() + val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) val actionListMarginTarget = spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) - val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + val mockExpandedChild = createMockExpandedChild() whenever( mockExpandedChild.findViewById<LinearLayout>( R.id.notification_action_list_margin_target @@ -479,20 +482,21 @@ class NotificationContentViewTest : SysuiTestCase() { // When: call NotificationContentView.onNotificationUpdated() to update the // NotificationEntry, which should not show bubble button - view.onNotificationUpdated(createMockNotificationEntry()) + view.onNotificationUpdated(kosmos.msgStyleBubbleableFullPerson) // Then: bottom margin of actionListMarginTarget should not change, still be 20 assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget)) } @Test + @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES) fun onNotificationUpdated_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() { // Given: bottom margin of actionListMarginTarget is notificationContentMargin - val mockNotificationEntry = createMockNotificationEntry() + val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) val actionListMarginTarget = spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) - val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + val mockExpandedChild = createMockExpandedChild() whenever( mockExpandedChild.findViewById<LinearLayout>( R.id.notification_action_list_margin_target @@ -506,7 +510,7 @@ class NotificationContentViewTest : SysuiTestCase() { // When: call NotificationContentView.onNotificationUpdated() to update the // NotificationEntry, which should show bubble button - view.onNotificationUpdated(createMockNotificationEntry(/*true*/ )) + view.onNotificationUpdated(kosmos.msgStyleBubbleableFullPerson) // Then: no bubble yet assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget)) @@ -514,7 +518,7 @@ class NotificationContentViewTest : SysuiTestCase() { // Given: controller says bubbles are enabled for the user view.setBubblesEnabledForUser(true) - // Then: bottom margin of actionListMarginTarget should not change, still be 20 + // Then: bottom margin of actionListMarginTarget should be changed to 0 assertEquals(0, getMarginBottom(actionListMarginTarget)) } @@ -611,15 +615,17 @@ class NotificationContentViewTest : SysuiTestCase() { private fun createMockContainingNotification(notificationEntry: NotificationEntry) = mock<ExpandableNotificationRow>().apply { - whenever(this.entry).thenReturn(notificationEntry) + if (!NotificationBundleUi.isEnabled) { + whenever(this.entryLegacy).thenReturn(notificationEntry) + } whenever(this.context).thenReturn(mContext) whenever(this.bubbleClickListener).thenReturn(View.OnClickListener {}) - whenever(this.entryAdapter).thenReturn(createMockNotificationEntryAdapter()) + whenever(this.entryAdapter).thenReturn(factory.create(notificationEntry)) } private fun createMockNotificationEntry() = mock<NotificationEntry>().apply { - whenever(mPeopleNotificationIdentifier.getPeopleNotificationType(this)) + whenever(kosmos.peopleNotificationIdentifier.getPeopleNotificationType(this)) .thenReturn(PeopleNotificationIdentifier.TYPE_FULL_PERSON) whenever(this.bubbleMetadata).thenReturn(mock()) val sbnMock: StatusBarNotification = mock() @@ -640,7 +646,7 @@ class NotificationContentViewTest : SysuiTestCase() { return innerLayout } - private fun createMockExpandedChild(notificationEntry: NotificationEntry) = + private fun createMockExpandedChild() = spy(createViewWithHeight(expandedHeight)).apply { whenever(this.findViewById<ImageView>(R.id.bubble_button)).thenReturn(mock()) whenever(this.findViewById<View>(R.id.actions_container)).thenReturn(mock()) @@ -661,9 +667,16 @@ class NotificationContentViewTest : SysuiTestCase() { val height = if (isSystemExpanded) expandedHeight else contractedHeight doReturn(height).whenever(row).intrinsicHeight - return spy(NotificationContentView(mContext, /* attrs= */ null)) + return NotificationContentView(mContext, /* attrs= */ null) .apply { - initialize(mPeopleNotificationIdentifier, mock(), mock(), mock(), mock(), mock()) + initialize( + kosmos.peopleNotificationIdentifier, + mock(), + mock(), + mock(), + mock(), + mock(), + ) setContainingNotification(row) setHeights( /* smallHeight= */ contractedHeight, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt index df3b1372614f..10de86644015 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt @@ -300,45 +300,6 @@ class NotificationGutsManagerWithScenesTest : SysuiTestCase() { } @Test - fun testChangeDensityOrFontScale() { - val guts = spy(NotificationGuts(mContext)) - whenever(guts.post(any())).thenAnswer { invocation: InvocationOnMock -> - handler.post((invocation.arguments[0] as Runnable)) - null - } - - // Test doesn't support animation since the guts view is not attached. - doNothing() - .whenever(guts) - .openControls(any<Int>(), any<Int>(), any<Boolean>(), any<Runnable>()) - val realRow = createTestNotificationRow() - val menuItem = createTestMenuItem(realRow) - val row = spy(realRow) - whenever(row!!.windowToken).thenReturn(Binder()) - whenever(row.guts).thenReturn(guts) - doNothing().whenever(row).ensureGutsInflated() - val realEntry = realRow!!.entry - val entry = spy(realEntry) - whenever(entry.row).thenReturn(row) - whenever(entry.getGuts()).thenReturn(guts) - Assert.assertTrue(gutsManager.openGutsInternal(row, 0, 0, menuItem)) - executor.runAllReady() - verify(guts).openControls(any<Int>(), any<Int>(), any<Boolean>(), any<Runnable>()) - - // called once by mGutsManager.bindGuts() in mGutsManager.openGuts() - verify(row).setGutsView(any()) - row.onDensityOrFontScaleChanged() - gutsManager.onDensityOrFontScaleChanged(entry) - executor.runAllReady() - gutsManager.closeAndSaveGuts(false, false, false, 0, 0, false) - verify(guts) - .closeControls(any<Boolean>(), any<Boolean>(), any<Int>(), any<Int>(), any<Boolean>()) - - // called again by mGutsManager.bindGuts(), in mGutsManager.onDensityOrFontScaleChanged() - verify(row, times(2)).setGutsView(any()) - } - - @Test fun testAppOpsSettingsIntent_camera() { val ops = ArraySet<Int>() ops.add(AppOpsManager.OP_CAMERA) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index ffb861db182c..063b546cbae9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -296,6 +296,7 @@ public class ScrimControllerTest extends SysuiTestCase { mKosmos.getTestDispatcher(), mLinearLargeScreenShadeInterpolator, new BlurConfig(0.0f, 0.0f), + mContext, mKosmos::getWindowRootViewBlurInteractor); mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible); mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront); @@ -1247,6 +1248,7 @@ public class ScrimControllerTest extends SysuiTestCase { mKosmos.getTestDispatcher(), mLinearLargeScreenShadeInterpolator, new BlurConfig(0.0f, 0.0f), + mContext, mKosmos::getWindowRootViewBlurInteractor); mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible); mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront); diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt index 9440280649dd..54ac3bf8220a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt @@ -21,6 +21,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.delay @@ -33,6 +34,7 @@ import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch @@ -50,11 +52,7 @@ import org.junit.runner.RunWith class PairwiseFlowTest : SysuiTestCase() { @Test fun simple() = runBlocking { - assertThatFlow((1..3).asFlow().pairwise()) - .emitsExactly( - WithPrev(1, 2), - WithPrev(2, 3), - ) + assertThatFlow((1..3).asFlow().pairwise()).emitsExactly(WithPrev(1, 2), WithPrev(2, 3)) } @Test fun notEnough() = runBlocking { assertThatFlow(flowOf(1).pairwise()).emitsNothing() } @@ -157,48 +155,27 @@ class SetChangesFlowTest : SysuiTestCase() { fun simple() = runBlocking { assertThatFlow(flowOf(setOf(1, 2, 3), setOf(2, 3, 4)).setChanges()) .emitsExactly( - SetChanges( - added = setOf(1, 2, 3), - removed = emptySet(), - ), - SetChanges( - added = setOf(4), - removed = setOf(1), - ), + SetChanges(added = setOf(1, 2, 3), removed = emptySet()), + SetChanges(added = setOf(4), removed = setOf(1)), ) } @Test fun onlyOneEmission() = runBlocking { assertThatFlow(flowOf(setOf(1)).setChanges()) - .emitsExactly( - SetChanges( - added = setOf(1), - removed = emptySet(), - ) - ) + .emitsExactly(SetChanges(added = setOf(1), removed = emptySet())) } @Test fun fromEmptySet() = runBlocking { assertThatFlow(flowOf(emptySet(), setOf(1, 2)).setChanges()) - .emitsExactly( - SetChanges( - removed = emptySet(), - added = setOf(1, 2), - ) - ) + .emitsExactly(SetChanges(removed = emptySet(), added = setOf(1, 2))) } @Test fun dontEmitFirstEvent() = runBlocking { assertThatFlow(flowOf(setOf(1, 2), setOf(2, 3)).setChanges(emitFirstEvent = false)) - .emitsExactly( - SetChanges( - removed = setOf(1), - added = setOf(3), - ) - ) + .emitsExactly(SetChanges(removed = setOf(1), added = setOf(3))) } } @@ -235,11 +212,7 @@ class SampleFlowTest : SysuiTestCase() { emit(4) } assertThatFlow(sampler.sample(samplee) { a, b -> a to b }) - .emitsExactly( - 2 to 1, - 3 to 3, - 4 to 3, - ) + .emitsExactly(2 to 1, 3 to 3, 4 to 3) } } @@ -419,10 +392,262 @@ class ThrottleFlowTest : SysuiTestCase() { } } +@SmallTest +@RunWith(AndroidJUnit4::class) +class SlidingWindowFlowTest : SysuiTestCase() { + + @Test + fun basicWindowing() = runTest { + val choreographer = createChoreographer(this) + val output = mutableListOf<List<Int>>() + val collectJob = + backgroundScope.launch { + (1..5) + .asFlow() + .onEach { delay(100) } + .slidingWindow(300.milliseconds, choreographer.fakeClock) + .toList(output) + } + + choreographer.advanceAndRun(0) + assertThat(output).isEmpty() + + choreographer.advanceAndRun(100) + assertThat(output).containsExactly(listOf(1)) + + choreographer.advanceAndRun(1) + assertThat(output).containsExactly(listOf(1)) + + choreographer.advanceAndRun(99) + assertThat(output).containsExactly(listOf(1), listOf(1, 2)) + + choreographer.advanceAndRun(100) + assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3)) + + choreographer.advanceAndRun(100) + assertThat(output) + .containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3), listOf(2, 3, 4)) + + choreographer.advanceAndRun(100) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(1, 2, 3), + listOf(2, 3, 4), + listOf(3, 4, 5), + ) + + choreographer.advanceAndRun(100) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(1, 2, 3), + listOf(2, 3, 4), + listOf(3, 4, 5), + listOf(4, 5), + ) + + choreographer.advanceAndRun(100) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(1, 2, 3), + listOf(2, 3, 4), + listOf(3, 4, 5), + listOf(4, 5), + listOf(5), + ) + + choreographer.advanceAndRun(100) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(1, 2, 3), + listOf(2, 3, 4), + listOf(3, 4, 5), + listOf(4, 5), + listOf(5), + emptyList<Int>(), + ) + + // Verify no more emissions + choreographer.advanceAndRun(9999999999) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(1, 2, 3), + listOf(2, 3, 4), + listOf(3, 4, 5), + listOf(4, 5), + listOf(5), + emptyList<Int>(), + ) + + assertThat(collectJob.isCompleted).isTrue() + } + + @Test + fun initialEmptyFlow() = runTest { + val choreographer = createChoreographer(this) + val output = mutableListOf<List<Int>>() + val collectJob = + backgroundScope.launch { + flow { + delay(200) + emit(1) + } + .slidingWindow(100.milliseconds, choreographer.fakeClock) + .toList(output) + } + + choreographer.advanceAndRun(0) + assertThat(output).isEmpty() + + choreographer.advanceAndRun(200) + assertThat(output).containsExactly(listOf(1)) + + choreographer.advanceAndRun(100) + assertThat(output).containsExactly(listOf(1), emptyList<Int>()) + + assertThat(collectJob.isCompleted).isTrue() + } + + @Test + fun windowLargerThanData() = runTest { + val choreographer = createChoreographer(this) + val output = mutableListOf<List<Int>>() + val collectJob = + backgroundScope.launch { + (1..3) + .asFlow() + .onEach { delay(50) } + .slidingWindow(500.milliseconds, choreographer.fakeClock) + .toList(output) + } + + choreographer.advanceAndRun(0) + assertThat(output).isEmpty() + + choreographer.advanceAndRun(50) + assertThat(output).containsExactly(listOf(1)) + + choreographer.advanceAndRun(50) + assertThat(output).containsExactly(listOf(1), listOf(1, 2)) + + choreographer.advanceAndRun(50) + assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3)) + + // It has been 100ms since the first emission, which means we have 400ms left until the + // first item is evicted from the window. Ensure that we have no evictions until that time. + choreographer.advanceAndRun(399) + assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3)) + + choreographer.advanceAndRun(1) + assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3), listOf(2, 3)) + + choreographer.advanceAndRun(50) + assertThat(output) + .containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3), listOf(2, 3), listOf(3)) + + choreographer.advanceAndRun(50) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(1, 2, 3), + listOf(2, 3), + listOf(3), + emptyList<Int>(), + ) + + assertThat(collectJob.isCompleted).isTrue() + } + + @Test + fun dataGapLargerThanWindow() = runTest { + val choreographer = createChoreographer(this) + val output = mutableListOf<List<Int>>() + val collectJob = + backgroundScope.launch { + flow { + emit(1) + delay(200) + emit(2) + delay(500) // Gap larger than window + emit(3) + } + .slidingWindow(300.milliseconds, choreographer.fakeClock) + .toList(output) + } + + choreographer.advanceAndRun(0) + assertThat(output).containsExactly(listOf(1)) + + choreographer.advanceAndRun(200) + assertThat(output).containsExactly(listOf(1), listOf(1, 2)) + + choreographer.advanceAndRun(100) + assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(2)) + + choreographer.advanceAndRun(200) + assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(2), emptyList<Int>()) + + choreographer.advanceAndRun(200) + assertThat(output) + .containsExactly(listOf(1), listOf(1, 2), listOf(2), emptyList<Int>(), listOf(3)) + + choreographer.advanceAndRun(300) + assertThat(output) + .containsExactly( + listOf(1), + listOf(1, 2), + listOf(2), + emptyList<Int>(), + listOf(3), + emptyList<Int>(), + ) + + assertThat(collectJob.isCompleted).isTrue() + } + + @Test + fun emptyFlow() = runTest { + val choreographer = createChoreographer(this) + val output = mutableListOf<List<Int>>() + + val collectJob = + backgroundScope.launch { + emptyFlow<Int>().slidingWindow(100.milliseconds).toList(output) + } + + choreographer.advanceAndRun(0) + assertThat(output).isEmpty() + + assertThat(collectJob.isCompleted).isTrue() + } + + private fun createChoreographer(testScope: TestScope) = + object { + val fakeClock = FakeSystemClock() + + fun advanceAndRun(millis: Long) { + fakeClock.advanceTime(millis) + testScope.advanceTimeBy(millis) + testScope.runCurrent() + } + } +} + private fun <T> assertThatFlow(flow: Flow<T>) = object { suspend fun emitsExactly(vararg emissions: T) = assertThat(flow.toList()).containsExactly(*emissions).inOrder() + suspend fun emitsNothing() = assertThat(flow.toList()).isEmpty() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java index e550e88b7bc7..846db6389d0c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java @@ -15,6 +15,7 @@ */ package com.android.systemui; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -28,7 +29,6 @@ import android.os.MessageQueue; import android.os.ParcelFileDescriptor; import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.flag.junit.SetFlagsRule; -import android.platform.test.ravenwood.RavenwoodClassRule; import android.platform.test.ravenwood.RavenwoodRule; import android.test.mock.MockContext; import android.testing.DexmakerShareClassLoaderRule; @@ -50,11 +50,13 @@ import com.android.systemui.log.LogWtfHandlerRule; import org.junit.After; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.mockito.Mockito; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.lang.annotation.Retention; @@ -93,23 +95,6 @@ public abstract class SysuiTestCase { public AndroidXAnimatorIsolationRule mAndroidXAnimatorIsolationRule = new AndroidXAnimatorIsolationRule(); - /** - * Rule that respects class-level annotations such as {@code @DisabledOnRavenwood} when tests - * are running on Ravenwood; on all other test environments this rule is a no-op passthrough. - */ - @ClassRule(order = Integer.MIN_VALUE + 1) - public static final RavenwoodClassRule sRavenwood = new RavenwoodClassRule(); - - /** - * Rule that defines and prepares the Ravenwood environment when tests are running on - * Ravenwood; on all other test environments this rule is a no-op passthrough. - */ - @Rule(order = Integer.MIN_VALUE + 1) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProcessApp() - .setProvideMainThread(true) - .build(); - @ClassRule public static final SetFlagsRule.ClassRule mSetFlagsClassRule = new SetFlagsRule.ClassRule( @@ -208,6 +193,7 @@ public abstract class SysuiTestCase { @Before public void SysuiSetup() throws Exception { + assertTempFilesAreCreatable(); ProtoLog.REQUIRE_PROTOLOGTOOL = false; mSysuiDependency = new SysuiTestDependency(mContext, shouldFailOnLeakedReceiver()); mDependency = mSysuiDependency.install(); @@ -229,6 +215,28 @@ public abstract class SysuiTestCase { } } + private static Boolean sCanCreateTempFiles = null; + + private static void assertTempFilesAreCreatable() { + // TODO(b/391948934): hopefully remove this hack + if (sCanCreateTempFiles == null) { + try { + File tempFile = File.createTempFile("confirm_temp_file_createable", "txt"); + sCanCreateTempFiles = true; + assertTrue(tempFile.delete()); + } catch (IOException e) { + sCanCreateTempFiles = false; + throw new RuntimeException(e); + } + } + if (!sCanCreateTempFiles) { + Assert.fail( + "Cannot create temp files, so mockito will probably fail (b/391948934). Temp" + + " folder should be: " + + System.getProperty("java.io.tmpdir")); + } + } + protected boolean shouldFailOnLeakedReceiver() { return false; } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java b/packages/SystemUI/tests/utils/src/com/android/systemui/condition/KosmosConditionTestExtensions.kt index 85297fe96d6a..c976b578437f 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/condition/KosmosConditionTestExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,22 +14,23 @@ * limitations under the License. */ -package android.platform.test.ravenwood; +package com.android.systemui.condition -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.runCurrent +import com.android.systemui.shared.condition.Condition -/** - * No longer needed. - * - * @deprecated this class used to be used to handle the class level annotation, which - * is now done by the test runner, so this class is not needed. - */ -@Deprecated -public class RavenwoodClassRule implements TestRule { - @Override - public Statement apply(Statement base, Description description) { - return base; +private val testCallback = + Condition.Callback { + // This is a no-op } + +fun Kosmos.testStart(condition: Condition) { + condition.addCallback(testCallback) + runCurrent() +} + +fun Kosmos.testStop(condition: Condition) { + condition.removeCallback(testCallback) + runCurrent() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt index 338e4bec7aa2..122e6a507cbf 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt @@ -16,6 +16,7 @@ package com.android.systemui.display.data.repository import android.view.Display +import com.android.app.displaylib.DisplayRepository.PendingDisplay import com.android.systemui.dagger.SysUISingleton import com.android.systemui.util.mockito.mock import dagger.Binds @@ -26,7 +27,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import com.android.app.displaylib.DisplayRepository.PendingDisplay import org.mockito.Mockito.`when` as whenever /** Creates a mock display. */ @@ -50,8 +50,7 @@ fun createPendingDisplay(id: Int = 0): PendingDisplay = class FakeDisplayRepository @Inject constructor() : DisplayRepository { private val flow = MutableStateFlow<Set<Display>>(emptySet()) private val displayIdFlow = MutableStateFlow<Set<Int>>(emptySet()) - private val pendingDisplayFlow = - MutableSharedFlow<PendingDisplay?>(replay = 1) + private val pendingDisplayFlow = MutableSharedFlow<PendingDisplay?>(replay = 1) private val displayAdditionEventFlow = MutableSharedFlow<Display?>(replay = 0) private val displayRemovalEventFlow = MutableSharedFlow<Int>(replay = 0) private val displayIdsWithSystemDecorationsFlow = MutableStateFlow<Set<Int>>(emptySet()) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt index 5ab3b3de49f4..4b516e9c74bc 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt @@ -16,6 +16,8 @@ package com.android.systemui.display.data.repository +import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown +import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl import com.android.systemui.dump.dumpManager import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt index 623989ec5809..c80d7386f67a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt @@ -81,6 +81,7 @@ import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlag import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor +import com.android.systemui.statusbar.notification.row.entryAdapterFactory import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor import com.android.systemui.statusbar.phone.fakeAutoHideControllerStore @@ -206,4 +207,5 @@ class KosmosJavaAdapter() { val displayTracker by lazy { kosmos.displayTracker } val fakeShadeDisplaysRepository by lazy { kosmos.fakeShadeDisplaysRepository } val sysUIStateDispatcher by lazy { kosmos.sysUIStateDispatcher } + val entryAdapterFactory by lazy { kosmos.entryAdapterFactory } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt index 11bd4c7b7940..54261c7f622b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt @@ -38,7 +38,9 @@ val Kosmos.sysUiStateFactory by Fixture { } } -val Kosmos.fakeSysUIStatePerDisplayRepository by Fixture { FakePerDisplayRepository<SysUiState>() } +val Kosmos.fakeSysUIStatePerDisplayRepository by Fixture { + FakePerDisplayRepository<SysUiState>().apply { add(Display.DEFAULT_DISPLAY, sysUiState) } +} val Kosmos.sysuiStateInteractor by Fixture { SysUIStateDisplaysInteractor(fakeSysUIStatePerDisplayRepository, displayRepository) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt index bd54fd471807..2cd270e97e61 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt @@ -19,7 +19,7 @@ package com.android.systemui.qs.panels.domain.interactor import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.panels.data.repository.iconAndNameCustomRepository import com.android.systemui.qs.panels.data.repository.stockTilesRepository -import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider +import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider val Kosmos.editTilesListInteractor by Kosmos.Fixture { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt index cc7eb6b4b3dc..7887762270c7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt @@ -17,12 +17,11 @@ package com.android.systemui.qs.panels.domain.interactor import android.os.UserHandle -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor import kotlinx.coroutines.flow.Flow -class FakeTileAvailabilityInteractor( - private val availabilityFlows: Map<Int, Flow<Boolean>> -) : QSTileAvailabilityInteractor { +class FakeTileAvailabilityInteractor(private val availabilityFlows: Map<Int, Flow<Boolean>>) : + QSTileAvailabilityInteractor { override fun availability(user: UserHandle): Flow<Boolean> { return availabilityFlows.getValue(user.identifier) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt index 40e6c75ee34a..6a65706e1f11 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt @@ -17,16 +17,13 @@ package com.android.systemui.qs.panels.domain.interactor import com.android.systemui.kosmos.Kosmos -import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor +import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor import com.android.systemui.user.data.repository.userRepository -var Kosmos.tileAvailabilityInteractorsMap by Kosmos.Fixture { - emptyMap<String, QSTileAvailabilityInteractor>() -} +var Kosmos.tileAvailabilityInteractorsMap by + Kosmos.Fixture { emptyMap<String, QSTileAvailabilityInteractor>() } -val Kosmos.newTilesAvailabilityInteractor by Kosmos.Fixture { - NewTilesAvailabilityInteractor( - tileAvailabilityInteractorsMap, - userRepository, - ) -} +val Kosmos.newTilesAvailabilityInteractor by + Kosmos.Fixture { + NewTilesAvailabilityInteractor(tileAvailabilityInteractorsMap, userRepository) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt index d97a5b2bede2..4823607c2993 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt @@ -29,7 +29,7 @@ import com.android.systemui.qs.pipeline.data.repository.tileSpecRepository import com.android.systemui.qs.pipeline.shared.logging.qsLogger import com.android.systemui.qs.pipeline.shared.pipelineFlagsRepository import com.android.systemui.qs.qsTileFactory -import com.android.systemui.qs.tiles.di.newQSTileFactory +import com.android.systemui.qs.tiles.base.ui.model.newQSTileFactory import com.android.systemui.settings.userTracker import com.android.systemui.user.data.repository.userRepository diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/FakeQSTileIntentUserInputHandler.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/FakeQSTileIntentUserInputHandler.kt index f50443ec4e86..1319787cc030 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/FakeQSTileIntentUserInputHandler.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/FakeQSTileIntentUserInputHandler.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.actions +package com.android.systemui.qs.tiles.base.domain.actions import android.app.PendingIntent import android.content.Intent @@ -34,7 +34,7 @@ class FakeQSTileIntentUserInputHandler : QSTileIntentUserInputHandler { override fun handle( expandable: Expandable?, intent: Intent, - handleDismissShadeShowOverLockScreenWhenLocked: Boolean + handleDismissShadeShowOverLockScreenWhenLocked: Boolean, ) { mutableInputs.add(Input.Intent(expandable, intent)) } @@ -42,7 +42,7 @@ class FakeQSTileIntentUserInputHandler : QSTileIntentUserInputHandler { override fun handle( expandable: Expandable?, pendingIntent: PendingIntent, - requestLaunchingDefaultActivity: Boolean + requestLaunchingDefaultActivity: Boolean, ) { mutableInputs.add( Input.PendingIntent(expandable, pendingIntent, requestLaunchingDefaultActivity) @@ -51,10 +51,11 @@ class FakeQSTileIntentUserInputHandler : QSTileIntentUserInputHandler { sealed interface Input { data class Intent(val expandable: Expandable?, val intent: android.content.Intent) : Input + data class PendingIntent( val expandable: Expandable?, val pendingIntent: android.app.PendingIntent, - val requestLaunchingDefaultActivity: Boolean + val requestLaunchingDefaultActivity: Boolean, ) : Input } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerKosmos.kt index ccfb6092a2e3..b884b8a8306b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerKosmos.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.actions +package com.android.systemui.qs.tiles.base.domain.actions import com.android.systemui.kosmos.Kosmos diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerSubject.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerSubject.kt index c1e689c0165c..3b7810ea22f0 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerSubject.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerSubject.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.actions +package com.android.systemui.qs.tiles.base.domain.actions import com.google.common.truth.FailureMetadata import com.google.common.truth.Subject @@ -24,11 +24,11 @@ import com.google.common.truth.Truth class QSTileIntentUserInputHandlerSubject private constructor( failureMetadata: FailureMetadata, - private val subject: FakeQSTileIntentUserInputHandler + private val subject: FakeQSTileIntentUserInputHandler, ) : Subject(failureMetadata, subject) { fun handledOneIntentInput( - intentAssertions: (FakeQSTileIntentUserInputHandler.Input.Intent) -> Unit = {}, + intentAssertions: (FakeQSTileIntentUserInputHandler.Input.Intent) -> Unit = {} ) { // check that there are no other inputs check("handledInputs").that(subject.handledInputs).hasSize(1) @@ -39,7 +39,7 @@ private constructor( } fun handledOnePendingIntentInput( - intentAssertions: (FakeQSTileIntentUserInputHandler.Input.PendingIntent) -> Unit = {}, + intentAssertions: (FakeQSTileIntentUserInputHandler.Input.PendingIntent) -> Unit = {} ) { // check that there are no other inputs check("handledInputs").that(subject.handledInputs).hasSize(1) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorKosmos.kt index 9ad49f052c9e..2ffc47972484 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorKosmos.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import com.android.systemui.kosmos.Kosmos diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeDisabledByPolicyInteractor.kt index fb6ba20e4c51..5bdeeab33f37 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeDisabledByPolicyInteractor.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import android.os.UserHandle import com.android.settingslib.RestrictedLockUtils @@ -23,7 +23,7 @@ class FakeDisabledByPolicyInteractor : DisabledByPolicyInteractor { override suspend fun isDisabled( user: UserHandle, - userRestriction: String? + userRestriction: String?, ): DisabledByPolicyInteractor.PolicyResult = if (userRestriction == DISABLED_RESTRICTION || userRestriction == DISABLED_RESTRICTION_2) { DisabledByPolicyInteractor.PolicyResult.TileDisabled( diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileDataInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileDataInteractor.kt index 3fcf8a93dc87..6bd8152665ac 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileDataInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileDataInteractor.kt @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor import android.os.UserHandle +import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.flatMapLatest @@ -26,6 +27,7 @@ class FakeQSTileDataInteractor<T> : QSTileDataInteractor<T> { private val dataFlow: MutableSharedFlow<T> = MutableSharedFlow(replay = 1) val dataSubscriptionCount get() = dataFlow.subscriptionCount + private val availabilityFlow: MutableSharedFlow<Boolean> = MutableSharedFlow(replay = 1) val availabilitySubscriptionCount get() = availabilityFlow.subscriptionCount @@ -42,6 +44,7 @@ class FakeQSTileDataInteractor<T> : QSTileDataInteractor<T> { suspend fun emitData(data: T): Unit = dataFlow.emit(data) fun tryEmitAvailability(isAvailable: Boolean): Boolean = availabilityFlow.tryEmit(isAvailable) + suspend fun emitAvailability(isAvailable: Boolean) = availabilityFlow.emit(isAvailable) override fun tileData(user: UserHandle, triggers: Flow<DataUpdateTrigger>): Flow<T> { @@ -58,5 +61,6 @@ class FakeQSTileDataInteractor<T> : QSTileDataInteractor<T> { } data class DataRequest(val user: UserHandle) + data class AvailabilityRequest(val user: UserHandle) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileUserActionInteractor.kt index c0584903db2d..8fd87a30e2fe 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileUserActionInteractor.kt @@ -14,10 +14,9 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.interactor -import com.android.systemui.plugins.qs.TileDetailsViewModel -import com.android.systemui.qs.FakeTileDetailsViewModel +import com.android.systemui.qs.tiles.base.domain.model.QSTileInput import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInputTestKtx.kt index 3943d1d7ec01..5c2b4a641b0e 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInputTestKtx.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.interactor +package com.android.systemui.qs.tiles.base.domain.model import android.os.UserHandle import com.android.systemui.animation.Expandable -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction object QSTileInputTestKtx { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/FakeQSTileConfigProvider.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/FakeQSTileConfigProvider.kt index d231d63a3906..97e65831b1d0 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/FakeQSTileConfigProvider.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/FakeQSTileConfigProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import com.android.systemui.qs.pipeline.shared.TileSpec diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderKosmos.kt index 1d579797bcb3..d1b410c4f5f3 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderKosmos.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import com.android.systemui.kosmos.Kosmos diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigTestBuilder.kt index 73d9b3233375..8938ebc2317e 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigTestBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.shared.model import com.android.internal.logging.InstanceId import com.android.systemui.qs.pipeline.shared.TileSpec @@ -33,14 +33,6 @@ object QSTileConfigTestBuilder { var policy: QSTilePolicy = QSTilePolicy.NoRestrictions var category: TileCategory = TileCategory.UNKNOWN - fun build() = - QSTileConfig( - tileSpec, - uiConfig, - instanceId, - category, - metricsSpec, - policy, - ) + fun build() = QSTileConfig(tileSpec, uiConfig, instanceId, category, metricsSpec, policy) } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsKosmos.kt index 146c1ad6ab70..753824b2a1c8 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsKosmos.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.base.analytics +package com.android.systemui.qs.tiles.base.ui.analytics import com.android.systemui.kosmos.Kosmos import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactoryKosmos.kt index c223be44a70c..3c2973077174 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactoryKosmos.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.di +package com.android.systemui.qs.tiles.base.ui.model import android.os.UserHandle import com.android.systemui.kosmos.Kosmos @@ -22,14 +22,14 @@ import com.android.systemui.qs.instanceIdSequenceFake import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.shared.model.TileCategory -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileState -import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction -import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel -import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider -import com.android.systemui.qs.tiles.viewmodel.qsTileViewModelAdaperFactory +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction +import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory +import com.android.systemui.qs.tiles.base.ui.viewmodel.qsTileViewModelAdaperFactory import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/QSTileStateSubject.kt index 657a95a3261e..54e85f1c2718 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/QSTileStateSubject.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,15 +14,11 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.impl.custom +package com.android.systemui.qs.tiles.base.ui.model -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.assertThat -import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.states -import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat -import com.android.systemui.qs.tiles.viewmodel.QSTileState +import com.android.systemui.qs.tiles.base.shared.model.QSTileState import com.google.common.truth.FailureMetadata import com.google.common.truth.Subject -import com.google.common.truth.Subject.Factory import com.google.common.truth.Truth /** diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapterKosmos.kt index de9f629ef787..cbadf8eb149d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapterKosmos.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 The Android Open Source Project + * Copyright (C) 2025 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.tiles.viewmodel +package com.android.systemui.qs.tiles.base.ui.viewmodel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt index 42437d5a5b81..77f561e3e9a6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt @@ -22,11 +22,12 @@ import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.activityStarter import com.android.systemui.qs.external.FakeCustomTileStatePersister -import com.android.systemui.qs.external.tileServices import com.android.systemui.qs.external.tileServicesFacade import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig +import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileDefaultsRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTilePackageUpdatesRepository import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileRepository @@ -34,8 +35,6 @@ import com.android.systemui.qs.tiles.impl.custom.data.repository.FakePackageMana import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileInteractor import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileServiceInteractor import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileUserActionInteractor -import com.android.systemui.qs.tiles.viewmodel.QSTileConfig -import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder import com.android.systemui.user.data.repository.userRepository import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt index ccba07273f1e..7b9d601c59ff 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt @@ -18,7 +18,7 @@ package com.android.systemui.qs.tiles.impl.custom.data.repository import android.content.ComponentName import android.os.UserHandle -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -31,7 +31,7 @@ class FakeCustomTileDefaultsRepository : CustomTileDefaultsRepository { private val defaultsFlow = MutableSharedFlow<DefaultsRequest>( replay = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST + onBufferOverflow = BufferOverflow.DROP_OLDEST, ) private val mutableDefaultsRequests: MutableList<DefaultsRequest> = mutableListOf() @@ -51,7 +51,7 @@ class FakeCustomTileDefaultsRepository : CustomTileDefaultsRepository { override fun requestNewDefaults( user: UserHandle, componentName: ComponentName, - force: Boolean + force: Boolean, ) { val request = DefaultsRequest(user, componentName, force) mutableDefaultsRequests.add(request) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt index c110da057a4e..c9ed71c3ae21 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt @@ -20,7 +20,7 @@ import android.os.UserHandle import android.service.quicksettings.Tile import com.android.systemui.qs.external.FakeCustomTileStatePersister import com.android.systemui.qs.pipeline.shared.TileSpec -import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults +import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.flow.Flow @@ -54,11 +54,8 @@ class FakeCustomTileRepository( override suspend fun isTileToggleable(): Boolean = realDelegate.isTileToggleable() - override suspend fun updateWithTile( - user: UserHandle, - newTile: Tile, - isPersistable: Boolean, - ) = realDelegate.updateWithTile(user, newTile, isPersistable) + override suspend fun updateWithTile(user: UserHandle, newTile: Tile, isPersistable: Boolean) = + realDelegate.updateWithTile(user, newTile, isPersistable) override suspend fun updateWithDefaults( user: UserHandle, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt index 3f07d05a4786..f94da17ad923 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt @@ -18,7 +18,7 @@ package com.android.systemui.qs.tiles.impl.modes.domain.interactor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.mainCoroutineContext -import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.modesDialogDelegate import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt index 537be4fc2527..5cd11e065553 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt @@ -23,17 +23,17 @@ import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.backgroundCoroutineContext import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope -import com.android.systemui.qrcodescanner.dagger.QRCodeScannerModule import com.android.systemui.qrcodescanner.qrCodeScannerController import com.android.systemui.qs.qsEventLogger -import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler -import com.android.systemui.qs.tiles.base.analytics.qsTileAnalytics -import com.android.systemui.qs.tiles.base.interactor.fakeDisabledByPolicyInteractor -import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelImpl +import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler +import com.android.systemui.qs.tiles.base.domain.interactor.fakeDisabledByPolicyInteractor +import com.android.systemui.qs.tiles.base.ui.analytics.qsTileAnalytics +import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelImpl import com.android.systemui.qs.tiles.impl.custom.qsTileLogger import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileDataInteractor import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileUserActionInteractor -import com.android.systemui.qs.tiles.impl.qr.ui.QRCodeScannerTileMapper +import com.android.systemui.qs.tiles.impl.qr.ui.mapper.QRCodeScannerTileMapper +import com.android.systemui.qs.tiles.impl.qr.ui.model.QRCodeScannerModule import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.time.systemClock @@ -45,7 +45,7 @@ val Kosmos.qrCodeScannerTileDataInteractor by QRCodeScannerTileDataInteractor( backgroundCoroutineContext, applicationCoroutineScope, - qrCodeScannerController + qrCodeScannerController, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt index 1fe18e3f4d8e..0045960c19ce 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt @@ -17,7 +17,7 @@ package com.android.systemui.qs.tiles.impl.uimodenight import android.content.res.Configuration -import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel +import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel import java.time.LocalTime object UiModeNightTileModelHelper { @@ -34,7 +34,7 @@ object UiModeNightTileModelHelper { nighModeCustomType: Int = DEFAULT_NIGHT_MODE_CUSTOM_TYPE, is24HourFormat: Boolean = false, customNightModeEnd: LocalTime = defaultCustomNightEnd, - customNightModeStart: LocalTime = defaultCustomNightStart + customNightModeStart: LocalTime = defaultCustomNightStart, ): UiModeNightTileModel { return UiModeNightTileModel( uiMode, @@ -44,7 +44,7 @@ object UiModeNightTileModelHelper { nighModeCustomType, is24HourFormat, customNightModeEnd, - customNightModeStart + customNightModeStart, ) } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java index 4efcada96a14..215df9d59ec9 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java @@ -58,7 +58,7 @@ public class GroupEntryBuilder { return this; } - /** Sets the creation time. */ + /** Sets the creation time. Should be SystemClock.elapsedRealtime */ public GroupEntryBuilder setCreationTime(long creationTime) { mCreationTime = creationTime; return this; diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilderKosmos.kt index 59f5ecd2563f..00c6c9445fe7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilderKosmos.kt @@ -14,18 +14,25 @@ * limitations under the License. */ -package com.android.systemui.statusbar.notification +package com.android.systemui.statusbar.notification.collection import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager.IMPORTANCE_DEFAULT import android.app.PendingIntent import android.app.Person import android.content.Intent import android.content.applicationContext +import android.graphics.Bitmap import android.graphics.drawable.Icon +import com.android.systemui.activity.EmptyTestActivity import com.android.systemui.kosmos.Kosmos -import com.android.systemui.statusbar.notification.collection.NotificationEntry -import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.icon.IconPack +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.PeopleNotificationType +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import com.android.systemui.statusbar.notification.promoted.setPromotedContent import org.mockito.kotlin.mock @@ -40,6 +47,11 @@ fun Kosmos.setIconPackWithMockIconViews(entry: NotificationEntry) { ) } +fun Kosmos.buildPromotedOngoingEntry( + block: NotificationEntryBuilder.() -> Unit = {} +): NotificationEntry = + buildNotificationEntry(tag = "ron", promoted = true, style = null, block = block) + fun Kosmos.buildOngoingCallEntry( promoted: Boolean = false, block: NotificationEntryBuilder.() -> Unit = {}, @@ -51,11 +63,6 @@ fun Kosmos.buildOngoingCallEntry( block = block, ) -fun Kosmos.buildPromotedOngoingEntry( - block: NotificationEntryBuilder.() -> Unit = {} -): NotificationEntry = - buildNotificationEntry(tag = "ron", promoted = true, style = null, block = block) - fun Kosmos.buildNotificationEntry( tag: String? = null, promoted: Boolean = false, @@ -88,3 +95,49 @@ private fun Kosmos.makeOngoingCallStyle(): Notification.CallStyle { val person = Person.Builder().setName("person").build() return Notification.CallStyle.forOngoingCall(person, pendingIntent) } + +private fun Kosmos.makeMessagingStyleNotification(): Notification.Builder { + val personIcon = Icon.createWithBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)) + val person = Person.Builder().setIcon(personIcon).setName("Person").build() + val message = Notification.MessagingStyle.Message("Message!", 4323, person) + val bubbleIntent = + PendingIntent.getActivity( + applicationContext, + 0, + Intent(applicationContext, EmptyTestActivity::class.java), + PendingIntent.FLAG_MUTABLE, + ) + + return Notification.Builder(applicationContext, "channelId") + .setSmallIcon(R.drawable.ic_person) + .setContentTitle("Title") + .setContentText("Text") + .setStyle(Notification.MessagingStyle(person).addMessage(message)) + .setBubbleMetadata( + Notification.BubbleMetadata.Builder( + bubbleIntent, + Icon.createWithResource(applicationContext, R.drawable.android), + ) + .setDeleteIntent(mock<PendingIntent>()) + .setDesiredHeight(314) + .setAutoExpandBubble(false) + .build() + ) +} + +fun Kosmos.makeEntryOfPeopleType(@PeopleNotificationType type: Int): NotificationEntryBuilder { + val channel = NotificationChannel("messages", "messages", IMPORTANCE_DEFAULT) + channel.isImportantConversation = (type == TYPE_IMPORTANT_PERSON) + channel.setConversationId("parent", "convo") + + val entry = + NotificationEntryBuilder().apply { + updateRanking { + it.setIsConversation(type != TYPE_NON_PERSON) + it.setShortcutInfo(if (type >= TYPE_FULL_PERSON) mock() else null) + it.setChannel(channel) + } + setNotification(makeMessagingStyleNotification().build()) + } + return entry +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryKosmos.kt new file mode 100644 index 000000000000..e127a70dc07d --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryKosmos.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON + +val Kosmos.msgStyleBubbleableFullPerson by + Kosmos.Fixture { makeEntryOfPeopleType(TYPE_FULL_PERSON).build() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt index 7ccbdb79101c..2523975c182c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt @@ -19,11 +19,9 @@ package com.android.systemui.statusbar.notification.row.ui.viewmodel import com.android.systemui.accessibility.domain.interactor.accessibilityInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture -import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor val Kosmos.activatableNotificationViewModel by Fixture { ActivatableNotificationViewModel.invoke( a11yInteractor = accessibilityInteractor, - windowRootViewBlurInteractor = windowRootViewBlurInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt index b906b6060245..81b134920f60 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt @@ -20,10 +20,12 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.statusbar.notification.row.ui.viewmodel.activatableNotificationViewModel import com.android.systemui.statusbar.notification.shelf.domain.interactor.notificationShelfInteractor +import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor val Kosmos.notificationShelfViewModel by Fixture { NotificationShelfViewModel( interactor = notificationShelfInteractor, + windowRootViewBlurInteractor = windowRootViewBlurInteractor, activatableViewModel = activatableNotificationViewModel, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt index f31697e82a45..a6332bf9e3d7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt @@ -289,6 +289,37 @@ class FakeSettings : SecureSettings, SystemSettings, UserSettingsProxy { return putString(name, value) } + override fun getInt(name: String): Int { + return getIntForUser(name, userId) + } + + override fun getInt(name: String, default: Int): Int { + return getIntForUser(name, default, userId) + } + + override fun getIntForUser(name: String, userHandle: Int): Int { + return getIntForUser(name, 0, userHandle) + } + + override fun getIntForUser(name: String, default: Int, userHandle: Int): Int { + return values[SettingsKey(userHandle, getUriFor(name).toString())]?.toInt() ?: default + } + + override fun putIntForUser(name: String, value: Int, userHandle: Int): Boolean { + val key = SettingsKey(userHandle, getUriFor(name).toString()) + values[key] = value.toString() + val uri = getUriFor(name) + contentObservers[key]?.onEach { it.dispatchChange(false, listOf(uri), 0, userHandle) } + contentObserversAllUsers[uri.toString()]?.onEach { + it.dispatchChange(false, listOf(uri), 0, userHandle) + } + return true + } + + override fun putInt(name: String, value: Int): Boolean { + return putIntForUser(name, value, userId) + } + /** Runs current jobs on dispatcher after calling the method. */ private fun <T> advanceDispatcher(f: () -> T): T { val result = f() diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING index 1148539187ac..083d2aa15316 100644 --- a/ravenwood/TEST_MAPPING +++ b/ravenwood/TEST_MAPPING @@ -180,9 +180,11 @@ // AUTO-GENERATED-END ], "ravenwood-postsubmit": [ - { - "name": "SystemUiRavenTests", - "host": true - } + // We haven't maintained SystemUiRavenTests, and as a result, it's been demoted already. + // Disable it until we fix the issues: b/319647875 + // { + // "name": "SystemUiRavenTests", + // "host": true + // } ] } diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java index 3cb2c67adf09..aa37d1221478 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java @@ -19,7 +19,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.EnabledOnRavenwood; -import android.platform.test.annotations.IgnoreUnderRavenwood; import org.junit.runner.Description; @@ -51,8 +50,6 @@ public class RavenwoodEnablementChecker { result = true; } else if (description.getAnnotation(DisabledOnRavenwood.class) != null) { result = false; - } else if (description.getAnnotation(IgnoreUnderRavenwood.class) != null) { - result = false; } if (result != null) { if (takeIntoAccountRunDisabledTestsFlag @@ -78,8 +75,6 @@ public class RavenwoodEnablementChecker { result = true; } else if (testClass.getAnnotation(DisabledOnRavenwood.class) != null) { result = false; - } else if (testClass.getAnnotation(IgnoreUnderRavenwood.class) != null) { - result = false; } if (!result) { if (takeIntoAccountRunDisabledTestsFlag diff --git a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java b/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java deleted file mode 100644 index 1c06829dba06..000000000000 --- a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2023 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.platform.test.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Test methods marked with this annotation are quietly ignored when running under a Ravenwood test - * environment. The test continues to execute normally under all other non-Ravenwood test - * environments. - * - * This annotation only takes effect when the containing class has a {@code - * RavenwoodRule} configured. Ignoring is accomplished by throwing an {@code org.junit - * .AssumptionViolatedException} which test infrastructure treats as being ignored. - * - * Developers are encouraged to use either the {@code blockedBy} and/or {@code reason} arguments - * to document why a test is being ignored, to aid in future audits of tests that are candidates - * to be enabled. - * - * @hide - * - * @deprecated Use {@link DisabledOnRavenwood} instead. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Deprecated -public @interface IgnoreUnderRavenwood { - /** - * One or more classes that aren't yet supported by Ravenwood, which this test depends on. - */ - Class<?>[] blockedBy() default {}; - - /** - * General free-form description of why this test is being ignored. - */ - String reason() default ""; - - /** - * Tracking bug number, if any. - */ - long bug() default 0; -} diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java index ffe5f6c8c579..b0b4c68cf9e0 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java @@ -100,38 +100,6 @@ public final class RavenwoodRule implements TestRule { } /** - * @deprecated no longer used. We always use an app UID. - */ - @Deprecated - public Builder setProcessSystem() { - return this; - } - - /** - * @deprecated no longer used. We always use an app UID. - */ - @Deprecated - public Builder setProcessApp() { - return this; - } - - /** - * @deprecated no longer used. - */ - @Deprecated - public Builder setPackageName(@NonNull String packageName) { - return this; - } - - /** - * @deprecated no longer used. Main thread is always available. - */ - @Deprecated - public Builder setProvideMainThread(boolean provideMainThread) { - return this; - } - - /** * Configure the given system property as immutable for the duration of the test. * Read access to the key is allowed, and write access will fail. When {@code value} is * {@code null}, the value is left as undefined. @@ -163,28 +131,12 @@ public final class RavenwoodRule implements TestRule { return this; } - /** - * @deprecated no longer used. All supported services are available. - */ - @Deprecated - public Builder setServicesRequired(@NonNull Class<?>... services) { - return this; - } - public RavenwoodRule build() { return mRule; } } /** - * @deprecated replaced by {@link #isOnRavenwood()} - */ - @Deprecated - public static boolean isUnderRavenwood() { - return IS_ON_RAVENWOOD; - } - - /** * Return if the current process is running on a Ravenwood test environment. */ public static boolean isOnRavenwood() { @@ -197,26 +149,6 @@ public final class RavenwoodRule implements TestRule { } } - /** - * @deprecated Use - * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getContext()} - * instead. - */ - @Deprecated - public Context getContext() { - return InstrumentationRegistry.getInstrumentation().getContext(); - } - - /** - * @deprecated Use - * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()} - * instead. - */ - @Deprecated - public Instrumentation getInstrumentation() { - return InstrumentationRegistry.getInstrumentation(); - } - @Override public Statement apply(Statement base, Description description) { if (!IS_ON_RAVENWOOD) { diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java index e8f59db86901..da2777803a64 100644 --- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java +++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java @@ -16,13 +16,11 @@ package com.android.ravenwoodtest.bivalenttest; import android.platform.test.annotations.DisabledOnRavenwood; -import android.platform.test.ravenwood.RavenwoodClassRule; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Assert; -import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,9 +31,6 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @DisabledOnRavenwood public class RavenwoodClassRuleDeviceOnlyTest { - @ClassRule - public static final RavenwoodClassRule sRavenwood = new RavenwoodClassRule(); - @Test public void testDeviceOnly() { Assert.assertFalse(RavenwoodRule.isOnRavenwood()); diff --git a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java index b1a40f082656..09286259e7d9 100644 --- a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java +++ b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java @@ -15,7 +15,7 @@ */ package com.android.ravenwoodtest; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -37,7 +37,7 @@ public class RavenwoodMinimumTest { } @Test - @IgnoreUnderRavenwood + @DisabledOnRavenwood public void testIgnored() { throw new RuntimeException("Shouldn't be executed under ravenwood"); } diff --git a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java index f833782bc8bb..2ff5dabcb277 100644 --- a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java +++ b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java @@ -18,37 +18,28 @@ package com.android.ravenwoodtest.servicestest; import static org.junit.Assert.assertEquals; -import android.platform.test.ravenwood.RavenwoodRule; import android.ravenwood.example.BlueManager; import android.ravenwood.example.RedManager; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class RavenwoodServicesDependenciesTest { - // NOTE: we carefully only ask for RedManager here, and rely on Ravenwood internals to spin - // up the implicit dependency on BlueManager - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProcessSystem() - .setServicesRequired(RedManager.class) - .build(); - @Test public void testDirect() { - final RedManager red = mRavenwood.getContext().getSystemService( - RedManager.class); + final RedManager red = InstrumentationRegistry.getInstrumentation().getContext() + .getSystemService(RedManager.class); assertEquals("blue+red", red.getInterfaceDescriptor()); } @Test public void testIndirect() { - final BlueManager blue = mRavenwood.getContext().getSystemService( - BlueManager.class); + final BlueManager blue = InstrumentationRegistry.getInstrumentation().getContext() + .getSystemService(BlueManager.class); assertEquals("blue", blue.getInterfaceDescriptor()); } } diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java index 23166a800245..0b9c45de6e40 100644 --- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java +++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java @@ -24,6 +24,8 @@ import static android.view.accessibility.AccessibilityManager.AUTOCLICK_IGNORE_M import static android.view.accessibility.AccessibilityManager.AUTOCLICK_REVERT_TO_LEFT_CLICK_DEFAULT; import static com.android.server.accessibility.autoclick.AutoclickIndicatorView.SHOW_INDICATOR_DELAY_TIME; +import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_DOUBLE_CLICK; +import static com.android.server.accessibility.autoclick.AutoclickScrollPanel.DIRECTION_NONE; import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_LEFT_CLICK; import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_RIGHT_CLICK; import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL; @@ -45,6 +47,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; +import android.view.ViewConfiguration; import android.view.WindowManager; import androidx.annotation.VisibleForTesting; @@ -95,6 +98,9 @@ public class AutoclickController extends BaseEventStreamTransformation { // Default click type is left-click. private @AutoclickType int mActiveClickType = AUTOCLICK_TYPE_LEFT_CLICK; + // Default scroll direction is DIRECTION_NONE. + private @AutoclickScrollPanel.ScrollDirection int mHoveredDirection = DIRECTION_NONE; + @VisibleForTesting final ClickPanelControllerInterface clickPanelController = new ClickPanelControllerInterface() { @@ -129,14 +135,26 @@ public class AutoclickController extends BaseEventStreamTransformation { final AutoclickScrollPanel.ScrollPanelControllerInterface mScrollPanelController = new AutoclickScrollPanel.ScrollPanelControllerInterface() { @Override - public void handleScroll(@AutoclickScrollPanel.ScrollDirection int direction) { - // TODO(b/388845721): Perform actual scroll. - } + public void onHoverButtonChange( + @AutoclickScrollPanel.ScrollDirection int direction, + boolean hovered) { + // Update the hover direction. + if (hovered) { + mHoveredDirection = direction; + } else if (mHoveredDirection == direction) { + // Safety check: Only clear hover tracking if this is the same button + // we're currently tracking. + mHoveredDirection = AutoclickScrollPanel.DIRECTION_NONE; + } - @Override - public void exitScrollMode() { - if (mAutoclickScrollPanel != null) { - mAutoclickScrollPanel.hide(); + // For exit button, we only trigger hover state changes, the autoclick system + // will handle the countdown. + if (direction == AutoclickScrollPanel.DIRECTION_EXIT) { + return; + } + // For direction buttons, perform scroll action immediately. + if (hovered && direction != AutoclickScrollPanel.DIRECTION_NONE) { + handleScroll(direction); } } }; @@ -283,6 +301,22 @@ public class AutoclickController extends BaseEventStreamTransformation { } } + /** + * Handles scroll operations in the specified direction. + */ + public void handleScroll(@AutoclickScrollPanel.ScrollDirection int direction) { + // TODO(b/388845721): Perform actual scroll. + } + + /** + * Exits scroll mode and hides the scroll panel UI. + */ + public void exitScrollMode() { + if (mAutoclickScrollPanel != null) { + mAutoclickScrollPanel.hide(); + } + } + @VisibleForTesting void onChangeForTesting(boolean selfChange, Uri uri) { mAutoclickSettingsObserver.onChange(selfChange, uri); @@ -774,6 +808,14 @@ public class AutoclickController extends BaseEventStreamTransformation { return; } + if (mAutoclickScrollPanel != null && mAutoclickScrollPanel.isVisible()) { + // If exit button is hovered, exit scroll mode after countdown and return early. + if (mHoveredDirection == AutoclickScrollPanel.DIRECTION_EXIT) { + exitScrollMode(); + } + return; + } + // Handle scroll type specially, show scroll panel instead of sending click events. if (mActiveClickType == AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL) { if (mAutoclickScrollPanel != null) { @@ -799,7 +841,7 @@ public class AutoclickController extends BaseEventStreamTransformation { final long now = SystemClock.uptimeMillis(); - int actionButton; + int actionButton = BUTTON_PRIMARY; if (mHoveredState) { // Always triggers left-click when the cursor hovers over the autoclick type // panel, to always allow users to change a different click type. Otherwise, if @@ -807,15 +849,32 @@ public class AutoclickController extends BaseEventStreamTransformation { // select other click types. actionButton = BUTTON_PRIMARY; } else { - actionButton = mActiveClickType == AUTOCLICK_TYPE_RIGHT_CLICK - ? BUTTON_SECONDARY - : BUTTON_PRIMARY; + switch (mActiveClickType) { + case AUTOCLICK_TYPE_LEFT_CLICK: + actionButton = BUTTON_PRIMARY; + break; + case AUTOCLICK_TYPE_RIGHT_CLICK: + actionButton = BUTTON_SECONDARY; + break; + case AUTOCLICK_TYPE_DOUBLE_CLICK: + actionButton = BUTTON_PRIMARY; + long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime(); + sendMotionEvent(actionButton, now); + sendMotionEvent(actionButton, now + doubleTapMinimumTimeout); + return; + default: + break; + } } + sendMotionEvent(actionButton, now); + } + + private void sendMotionEvent(int actionButton, long eventTime) { MotionEvent downEvent = MotionEvent.obtain( - /* downTime= */ now, - /* eventTime= */ now, + /* downTime= */ eventTime, + /* eventTime= */ eventTime, MotionEvent.ACTION_DOWN, /* pointerCount= */ 1, mTempPointerProperties, diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java index e79be502a6fc..c71443149687 100644 --- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java +++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java @@ -23,6 +23,7 @@ import android.content.Context; import android.graphics.PixelFormat; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.WindowInsets; import android.view.WindowManager; @@ -41,12 +42,16 @@ public class AutoclickScrollPanel { public static final int DIRECTION_DOWN = 1; public static final int DIRECTION_LEFT = 2; public static final int DIRECTION_RIGHT = 3; + public static final int DIRECTION_EXIT = 4; + public static final int DIRECTION_NONE = 5; @IntDef({ DIRECTION_UP, DIRECTION_DOWN, DIRECTION_LEFT, - DIRECTION_RIGHT + DIRECTION_RIGHT, + DIRECTION_EXIT, + DIRECTION_NONE, }) @Retention(RetentionPolicy.SOURCE) public @interface ScrollDirection {} @@ -70,16 +75,12 @@ public class AutoclickScrollPanel { */ public interface ScrollPanelControllerInterface { /** - * Called when a scroll direction is hovered. + * Called when a button hover state changes. * - * @param direction The direction to scroll: one of {@link ScrollDirection} values. + * @param direction The direction associated with the button. + * @param hovered Whether the button is being hovered or not. */ - void handleScroll(@ScrollDirection int direction); - - /** - * Called when the exit button is hovered. - */ - void exitScrollMode(); + void onHoverButtonChange(@ScrollDirection int direction, boolean hovered); } public AutoclickScrollPanel(Context context, WindowManager windowManager, @@ -104,19 +105,12 @@ public class AutoclickScrollPanel { * Sets up hover listeners for scroll panel buttons. */ private void initializeButtonState() { - // Set up hover listeners for direction buttons. - setupHoverListenerForDirectionButton(mUpButton, DIRECTION_UP); - setupHoverListenerForDirectionButton(mLeftButton, DIRECTION_LEFT); - setupHoverListenerForDirectionButton(mRightButton, DIRECTION_RIGHT); - setupHoverListenerForDirectionButton(mDownButton, DIRECTION_DOWN); - - // Set up hover listener for exit button. - mExitButton.setOnHoverListener((v, event) -> { - if (mScrollPanelController != null) { - mScrollPanelController.exitScrollMode(); - } - return true; - }); + // Set up hover listeners for all buttons. + setupHoverListenerForButton(mUpButton, DIRECTION_UP); + setupHoverListenerForButton(mLeftButton, DIRECTION_LEFT); + setupHoverListenerForButton(mRightButton, DIRECTION_RIGHT); + setupHoverListenerForButton(mDownButton, DIRECTION_DOWN); + setupHoverListenerForButton(mExitButton, DIRECTION_EXIT); } /** @@ -142,14 +136,37 @@ public class AutoclickScrollPanel { } /** - * Sets up a hover listener for a direction button. + * Sets up a hover listener for a button. */ - private void setupHoverListenerForDirectionButton(ImageButton button, - @ScrollDirection int direction) { + private void setupHoverListenerForButton(ImageButton button, @ScrollDirection int direction) { button.setOnHoverListener((v, event) -> { - if (mScrollPanelController != null) { - mScrollPanelController.handleScroll(direction); + if (mScrollPanelController == null) { + return true; + } + + boolean hovered; + switch (event.getAction()) { + case MotionEvent.ACTION_HOVER_ENTER: + hovered = true; + break; + case MotionEvent.ACTION_HOVER_MOVE: + // For direction buttons, continuously trigger scroll on hover move. + if (direction != DIRECTION_EXIT) { + hovered = true; + } else { + // Ignore hover move events for exit button. + return true; + } + break; + case MotionEvent.ACTION_HOVER_EXIT: + hovered = false; + break; + default: + return true; } + + // Notify the controller about the hover change. + mScrollPanelController.onHoverButtonChange(direction, hovered); return true; }); } diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java index 5a484d42eb96..c29829fb770f 100644 --- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java +++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java @@ -576,7 +576,7 @@ public class AutoclickTypePanel { private WindowManager.LayoutParams getDefaultLayoutParams() { final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; - layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; layoutParams.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; layoutParams.setFitInsetsTypes(WindowInsets.Type.statusBars()); layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; diff --git a/services/companion/java/com/android/server/companion/virtual/SensorController.java b/services/companion/java/com/android/server/companion/virtual/SensorController.java index 88b791046c87..6e098d014ee3 100644 --- a/services/companion/java/com/android/server/companion/virtual/SensorController.java +++ b/services/companion/java/com/android/server/companion/virtual/SensorController.java @@ -21,15 +21,18 @@ import android.annotation.Nullable; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.sensor.IVirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensor; +import android.companion.virtual.sensor.VirtualSensorAdditionalInfo; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorEvent; import android.content.AttributionSource; +import android.hardware.SensorAdditionalInfo; import android.hardware.SensorDirectChannel; import android.os.Binder; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.SharedMemory; +import android.os.SystemClock; import android.util.ArrayMap; import android.util.Slog; import android.util.SparseArray; @@ -140,7 +143,7 @@ public class SensorController { final IBinder sensorToken = new Binder("android.hardware.sensor.VirtualSensor:" + config.getName()); VirtualSensor sensor = new VirtualSensor(handle, config.getType(), config.getName(), - virtualDevice, sensorToken); + config.getFlags(), virtualDevice, sensorToken); synchronized (mLock) { mSensorDescriptors.put(sensorToken, sensorDescriptor); mVirtualSensors.put(handle, sensor); @@ -164,6 +167,37 @@ public class SensorController { } } + boolean sendSensorAdditionalInfo(@NonNull IBinder token, + @NonNull VirtualSensorAdditionalInfo info) { + Objects.requireNonNull(token); + Objects.requireNonNull(info); + synchronized (mLock) { + final SensorDescriptor sensorDescriptor = mSensorDescriptors.get(token); + long timestamp = SystemClock.elapsedRealtimeNanos(); + if (sensorDescriptor == null) { + throw new IllegalArgumentException("Could not send sensor event for given token"); + } + if (!mSensorManagerInternal.sendSensorAdditionalInfo( + sensorDescriptor.getHandle(), SensorAdditionalInfo.TYPE_FRAME_BEGIN, + /* serial= */ 0, timestamp++, /* values= */ null)) { + return false; + } + for (int i = 0; i < info.getValues().size(); ++i) { + if (!mSensorManagerInternal.sendSensorAdditionalInfo( + sensorDescriptor.getHandle(), info.getType(), /* serial= */ i, + timestamp++, info.getValues().get(i))) { + return false; + } + } + if (!mSensorManagerInternal.sendSensorAdditionalInfo( + sensorDescriptor.getHandle(), SensorAdditionalInfo.TYPE_FRAME_END, + /* serial= */ 0, timestamp, /* values= */ null)) { + return false; + } + } + return true; + } + @Nullable VirtualSensor getSensorByHandle(int handle) { synchronized (mLock) { diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 28efdfc01ee2..0023b6d53837 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -55,6 +55,7 @@ import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; import android.companion.virtual.camera.VirtualCameraConfig; import android.companion.virtual.sensor.VirtualSensor; +import android.companion.virtual.sensor.VirtualSensorAdditionalInfo; import android.companion.virtual.sensor.VirtualSensorEvent; import android.companion.virtualdevice.flags.Flags; import android.compat.annotation.ChangeId; @@ -1294,6 +1295,18 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } @Override // Binder call + public boolean sendSensorAdditionalInfo(@NonNull IBinder token, + @NonNull VirtualSensorAdditionalInfo info) { + checkCallerIsDeviceOwner(); + final long ident = Binder.clearCallingIdentity(); + try { + return mSensorController.sendSensorAdditionalInfo(token, info); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call public void registerIntentInterceptor(IVirtualDeviceIntentInterceptor intentInterceptor, IntentFilter filter) { checkCallerIsDeviceOwner(); diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java index 7eb7072520de..a1d39faa7039 100644 --- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java +++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java @@ -313,7 +313,8 @@ public class ContextualSearchManagerService extends SystemService { android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS }) - private Intent getContextualSearchIntent(int entrypoint, int userId, CallbackToken mToken) { + private Intent getContextualSearchIntent(int entrypoint, int userId, String callingPackage, + CallbackToken mToken) { final Intent launchIntent = getResolvedLaunchIntent(userId); if (launchIntent == null) { if (DEBUG) Log.w(TAG, "Failed getContextualSearchIntent: launchIntent is null"); @@ -332,6 +333,9 @@ public class ContextualSearchManagerService extends SystemService { launchIntent.putExtra(ContextualSearchManager.EXTRA_IS_AUDIO_PLAYING, mAudioManager.isMusicActive()); } + if (Flags.selfInvocation()) { + launchIntent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage); + } boolean isAssistDataAllowed = mAtmInternal.isAssistDataAllowed(); final List<ActivityAssistInfo> records = mAtmInternal.getTopVisibleActivities(); final List<IBinder> activityTokens = new ArrayList<>(records.size()); @@ -500,6 +504,7 @@ public class ContextualSearchManagerService extends SystemService { } private void startContextualSearchInternal(int entrypoint) { + final String callingPackage = mPackageManager.getNameForUid(Binder.getCallingUid()); final int callingUserId = Binder.getCallingUserHandle().getIdentifier(); mAssistDataRequester.cancel(); // Creates a new CallbackToken at mToken and an expiration handler. @@ -508,7 +513,8 @@ public class ContextualSearchManagerService extends SystemService { // server has READ_FRAME_BUFFER permission to get the screenshot and because only // the system server can invoke non-exported activities. Binder.withCleanCallingIdentity(() -> { - Intent launchIntent = getContextualSearchIntent(entrypoint, callingUserId, mToken); + Intent launchIntent = getContextualSearchIntent(entrypoint, callingUserId, + callingPackage, mToken); if (launchIntent != null) { int result = invokeContextualSearchIntent(launchIntent, callingUserId); if (DEBUG) { diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index b75b7ddf8181..76dd6a504d8c 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -2816,10 +2816,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (!checkNotifyPermission("notifyEmergencyNumberList()")) { return; } - if (!mContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_TELEPHONY_CALLING)) { + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + && !mContext.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)) { // TelephonyManager.getEmergencyNumberList() throws an exception if - // FEATURE_TELEPHONY_CALLING is not defined. + // FEATURE_TELEPHONY_CALLING or FEATURE_TELEPHONY_MESSAGING is not defined. return; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 76ba0054583b..59c5e0e7fc2c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -137,6 +137,7 @@ import static android.security.Flags.preventIntentRedirectThrowExceptionIfNested import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS; import static android.view.Display.INVALID_DISPLAY; +import static com.android.internal.util.FrameworkStatsLog.EXTRA_INTENT_KEYS_COLLECTED_ON_SERVER; import static com.android.internal.util.FrameworkStatsLog.INTENT_CREATOR_TOKEN_ADDED; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NEW_MUTABLE_IMPLICIT_PENDING_INTENT_RETRIEVED; import static com.android.sdksandbox.flags.Flags.sdkSandboxInstrumentationInfo; @@ -2004,7 +2005,7 @@ public class ActivityManagerService extends IActivityManager.Stub new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName, String persistentDeviceId) { - if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) { + if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && uid >= 0) { if (getAppOpsManager().checkOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { runInBackgroundDisabled(uid); @@ -19415,12 +19416,14 @@ public class ActivityManagerService extends IActivityManager.Stub if (!preventIntentRedirect()) return; if (intent == null) return; + int callingUid = Binder.getCallingUid(); if (((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED) == 0) && intent.getExtras() != null && intent.getExtras().hasIntent()) { Slog.wtf(TAG, "[IntentRedirect Hardening] The intent does not have its nested keys collected as a " + "preparation for creating intent creator tokens. Intent: " + intent + "; creatorPackage: " + creatorPackage); + FrameworkStatsLog.write(EXTRA_INTENT_KEYS_COLLECTED_ON_SERVER, callingUid); if (preventIntentRedirectShowToastIfNestedKeysNotCollectedRW()) { UiThread.getHandler().post( () -> Toast.makeText(mContext, @@ -19447,7 +19450,7 @@ public class ActivityManagerService extends IActivityManager.Stub targetPackage); final boolean noExtraIntentKeys = intent.getExtraIntentKeys() == null || intent.getExtraIntentKeys().isEmpty(); - final int creatorUid = noExtraIntentKeys ? DEFAULT_INTENT_CREATOR_UID : Binder.getCallingUid(); + final int creatorUid = noExtraIntentKeys ? DEFAULT_INTENT_CREATOR_UID : callingUid; intent.forEachNestedCreatorToken(extraIntent -> { if (isCreatorSameAsTarget) { diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java index a47beae1d9cb..800e2b2d9657 100644 --- a/services/core/java/com/android/server/am/AppPermissionTracker.java +++ b/services/core/java/com/android/server/am/AppPermissionTracker.java @@ -394,6 +394,7 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy private class MyAppOpsCallback extends IAppOpsCallback.Stub { @Override public void opChanged(int op, int uid, String packageName, String persistentDeviceId) { + if (uid < 0) return; mHandler.obtainMessage(MyHandler.MSG_APPOPS_CHANGED, op, uid, packageName) .sendToTarget(); } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index fa35da30bf4b..115ae41d12ff 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -2643,7 +2643,7 @@ public class OomAdjuster { } capability |= getDefaultCapability(app, procState); - capability |= getCpuCapability(app, now); + capability |= getCpuCapability(app, now, foregroundActivities); // Procstates below BFGS should never have this capability. if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { @@ -3422,15 +3422,18 @@ public class OomAdjuster { return baseCapabilities | networkCapabilities; } - private static int getCpuCapability(ProcessRecord app, long nowUptime) { + private static int getCpuCapability(ProcessRecord app, long nowUptime, + boolean hasForegroundActivities) { // Note: persistent processes get all capabilities, including CPU_TIME. final UidRecord uidRec = app.getUidRecord(); if (uidRec != null && uidRec.isCurAllowListed()) { // Process is in the power allowlist. return PROCESS_CAPABILITY_CPU_TIME; } - if (app.mState.getCachedHasVisibleActivities()) { - // Process has user visible activities. + if (hasForegroundActivities) { + // TODO: b/402987519 - This grants the Top Sleeping process CPU_TIME but eventually + // should not. + // Process has user perceptible activities. return PROCESS_CAPABILITY_CPU_TIME; } if (Flags.prototypeAggressiveFreezing()) { diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index fb33cb1ff8c0..5ecac2253b49 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -182,6 +182,7 @@ import com.android.server.SystemServiceManager; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.pm.PackageList; import com.android.server.pm.PackageManagerLocal; +import com.android.server.pm.ProtectedPackages; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageState; @@ -311,6 +312,8 @@ public class AppOpsService extends IAppOpsService.Stub { private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); + private ProtectedPackages mProtectedPackages; + /** * Registered callbacks, called from {@link #collectAsyncNotedOp}. * @@ -822,7 +825,8 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public void onOpModeChanged(int op, int uid, String packageName, String persistentDeviceId) throws RemoteException { - mCallback.opChanged(op, uid, packageName, persistentDeviceId); + mCallback.opChanged(op, uid, packageName != null ? packageName : "", + Objects.requireNonNull(persistentDeviceId)); } } @@ -1059,7 +1063,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (Flags.enableAllSqliteAppopsAccesses()) { mHistoricalRegistry = new HistoricalRegistrySql(context); } else { - mHistoricalRegistry = new HistoricalRegistry(this, context); + mHistoricalRegistry = new LegacyHistoricalRegistry(this, context); } } @@ -2127,6 +2131,12 @@ public class AppOpsService extends IAppOpsService.Stub { enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); verifyIncomingOp(code); + + if (isDeviceProvisioningPackage(uid, null)) { + Slog.w(TAG, "Cannot set uid mode for device provisioning app by Shell"); + return; + } + code = AppOpsManager.opToSwitch(code); if (permissionPolicyCallback == null) { @@ -2437,6 +2447,11 @@ public class AppOpsService extends IAppOpsService.Stub { return; } + if (isDeviceProvisioningPackage(uid, packageName)) { + Slog.w(TAG, "Cannot set op mode for device provisioning app by Shell"); + return; + } + code = AppOpsManager.opToSwitch(code); PackageVerificationResult pvr; @@ -2467,6 +2482,36 @@ public class AppOpsService extends IAppOpsService.Stub { notifyStorageManagerOpModeChangedSync(code, uid, packageName, mode, previousMode); } + // Device provisioning package is restricted from setting app op mode through shell command + private boolean isDeviceProvisioningPackage(int uid, + @Nullable String packageName) { + if (UserHandle.getAppId(Binder.getCallingUid()) == Process.SHELL_UID) { + ProtectedPackages protectedPackages = getProtectedPackages(); + + if (packageName != null && protectedPackages.isDeviceProvisioningPackage(packageName)) { + return true; + } + + String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); + if (packageNames != null) { + for (String pkg : packageNames) { + if (protectedPackages.isDeviceProvisioningPackage(pkg)) { + return true; + } + } + } + } + return false; + } + + // Race condition is allowed here for better performance + private ProtectedPackages getProtectedPackages() { + if (mProtectedPackages == null) { + mProtectedPackages = new ProtectedPackages(mContext); + } + return mProtectedPackages; + } + private void notifyOpChanged(ArraySet<OnOpModeChangedListener> callbacks, int code, int uid, String packageName, String persistentDeviceId) { for (int i = 0; i < callbacks.size(); i++) { @@ -7011,7 +7056,8 @@ public class AppOpsService extends IAppOpsService.Stub { mHistoricalRegistry = new HistoricalRegistrySql( (HistoricalRegistrySql) mHistoricalRegistry); } else { - mHistoricalRegistry = new HistoricalRegistry((HistoricalRegistry) mHistoricalRegistry); + mHistoricalRegistry = new LegacyHistoricalRegistry( + (LegacyHistoricalRegistry) mHistoricalRegistry); } mHistoricalRegistry.systemReady(mContext.getContentResolver()); diff --git a/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java index 70b7016fbb90..3867cbe1e98b 100644 --- a/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java +++ b/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java @@ -82,9 +82,8 @@ import java.util.Set; * INITIALIZATION: We can initialize persistence only after the system is ready * as we need to check the optional configuration override from the settings * database which is not initialized at the time the app ops service is created. This class - * relies on {@link HistoricalRegistry} for controlling that no calls are allowed until then. All - * outside calls are going through {@link HistoricalRegistry}. - * + * relies on {@link LegacyHistoricalRegistry} for controlling that no calls are allowed until then. + * All outside calls are going through {@link LegacyHistoricalRegistry}. */ abstract class DiscreteOpsRegistry { private static final String TAG = DiscreteOpsRegistry.class.getSimpleName(); diff --git a/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java index 20706b659ffb..771df19ec906 100644 --- a/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java +++ b/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java @@ -81,7 +81,7 @@ import java.util.Set; * THREADING AND LOCKING: * For in-memory transactions this class relies on {@link DiscreteOpsXmlRegistry#mInMemoryLock}. * It is assumed that the same lock is used for in-memory transactions in {@link AppOpsService}, - * {@link HistoricalRegistry}, and {@link DiscreteOpsXmlRegistry }. + * {@link LegacyHistoricalRegistry}, and {@link DiscreteOpsXmlRegistry }. * {@link DiscreteOpsRegistry#recordDiscreteAccess} must only be called while holding this lock. * {@link DiscreteOpsXmlRegistry#mOnDiskLock} is used when disk transactions are performed. * It is very important to release {@link DiscreteOpsXmlRegistry#mInMemoryLock} as soon as diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/LegacyHistoricalRegistry.java index a8128dd11cfe..f4f5775bbced 100644 --- a/services/core/java/com/android/server/appop/HistoricalRegistry.java +++ b/services/core/java/com/android/server/appop/LegacyHistoricalRegistry.java @@ -128,11 +128,11 @@ import java.util.concurrent.TimeUnit; */ // TODO (bug:122218838): Make sure we handle start of epoch time // TODO (bug:122218838): Validate changed time is handled correctly -final class HistoricalRegistry implements HistoricalRegistryInterface { +final class LegacyHistoricalRegistry implements HistoricalRegistryInterface { private static final boolean DEBUG = false; private static final boolean KEEP_WTF_LOG = Build.IS_DEBUGGABLE; - private static final String LOG_TAG = HistoricalRegistry.class.getSimpleName(); + private static final String LOG_TAG = LegacyHistoricalRegistry.class.getSimpleName(); private static final String PARAMETER_DELIMITER = ","; private static final String PARAMETER_ASSIGNMENT = "="; @@ -200,7 +200,7 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { private final Context mContext; - HistoricalRegistry(@NonNull Object lock, Context context) { + LegacyHistoricalRegistry(@NonNull Object lock, Context context) { mInMemoryLock = lock; mContext = context; if (Flags.enableSqliteAppopsAccesses()) { @@ -210,7 +210,7 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { } } - HistoricalRegistry(@NonNull HistoricalRegistry other) { + LegacyHistoricalRegistry(@NonNull LegacyHistoricalRegistry other) { this(other.mInMemoryLock, other.mContext); mMode = other.mMode; mBaseSnapshotInterval = other.mBaseSnapshotInterval; @@ -313,9 +313,9 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { final int mode = AppOpsManager.parseHistoricalMode(modeValue); final long baseSnapshotInterval = Long.parseLong(baseSnapshotIntervalValue); final int intervalCompressionMultiplier = Integer.parseInt(intervalMultiplierValue); - setHistoryParameters(mode, baseSnapshotInterval,intervalCompressionMultiplier); + setHistoryParameters(mode, baseSnapshotInterval, intervalCompressionMultiplier); return; - } catch (NumberFormatException ignored) {} + } catch (NumberFormatException ignored) { } } Slog.w(LOG_TAG, "Bad value for" + Settings.Global.APPOP_HISTORY_PARAMETERS + "=" + setting + " resetting!"); @@ -805,7 +805,7 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { private void schedulePersistHistoricalOpsMLocked(@NonNull HistoricalOps ops) { final Message message = PooledLambda.obtainMessage( - HistoricalRegistry::persistPendingHistory, HistoricalRegistry.this); + LegacyHistoricalRegistry::persistPendingHistory, LegacyHistoricalRegistry.this); message.what = MSG_WRITE_PENDING_HISTORY; IoThread.getHandler().sendMessage(message); mPendingWrites.offerFirst(ops); @@ -813,7 +813,7 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { private static void makeRelativeToEpochStart(@NonNull HistoricalOps ops, long nowMillis) { ops.setBeginAndEndTime(nowMillis - ops.getEndTimeMillis(), - nowMillis- ops.getBeginTimeMillis()); + nowMillis - ops.getBeginTimeMillis()); } private void pruneFutureOps(@NonNull List<HistoricalOps> ops) { @@ -979,7 +979,7 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { final HistoricalOps readOp = readOps.get(i); currentOps.merge(readOp); } - } + } } private @Nullable LinkedList<HistoricalOps> collectHistoricalOpsBaseDLocked(int filterUid, @@ -1125,7 +1125,7 @@ final class HistoricalRegistry implements HistoricalRegistryInterface { if (existingOpCount > 0) { // Compute elapsed time final long elapsedTimeMillis = passedOps.get(passedOps.size() - 1) - .getEndTimeMillis(); + .getEndTimeMillis(); for (int i = 0; i < existingOpCount; i++) { final HistoricalOps existingOp = existingOps.get(i); existingOp.offsetBeginAndEndTime(elapsedTimeMillis); diff --git a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java index 7502664a9628..180ef855cfda 100644 --- a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java +++ b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java @@ -39,6 +39,7 @@ import android.os.Trace; import android.os.UserHandle; import android.util.ArraySet; import android.util.IntArray; +import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.media.permission.INativePermissionController; @@ -62,6 +63,8 @@ import java.util.stream.Collectors; /** Responsible for synchronizing system server permission state to the native audioserver. */ public class AudioServerPermissionProvider { + static final String TAG = "AudioServerPermissionProvider"; + static final String[] MONITORED_PERMS = new String[PermissionEnum.ENUM_SIZE]; static final byte[] HDS_PERMS = new byte[] {PermissionEnum.CAPTURE_AUDIO_HOTWORD, @@ -219,10 +222,13 @@ public class AudioServerPermissionProvider { public void setIsolatedServiceUid(int uid, int owningUid) { synchronized (mLock) { if (mHdsUid == uid) return; - var packageNameSet = mPackageMap.get(owningUid); - if (packageNameSet == null) return; - var packageName = packageNameSet.iterator().next(); - onModifyPackageState(uid, packageName, /* isRemove= */ false); + var packageNameSet = mPackageMap.get(UserHandle.getAppId(owningUid)); + if (packageNameSet != null) { + var packageName = packageNameSet.iterator().next(); + onModifyPackageState(uid, packageName, /* isRemove= */ false); + } else { + Log.wtf(TAG, "setIsolatedService owning uid not found"); + } // permissions mHdsUid = uid; if (mDest == null) { @@ -249,11 +255,19 @@ public class AudioServerPermissionProvider { public void clearIsolatedServiceUid(int uid) { synchronized (mLock) { - if (mHdsUid != uid) return; - var packageNameSet = mPackageMap.get(uid); - if (packageNameSet == null) return; - var packageName = packageNameSet.iterator().next(); - onModifyPackageState(uid, packageName, /* isRemove= */ true); + var packageNameSet = mPackageMap.get(UserHandle.getAppId(uid)); + if (mHdsUid != uid) { + Log.wtf(TAG, + "Unexpected isolated service uid cleared: " + uid + packageNameSet + + ", expected " + mHdsUid); + return; + } + if (packageNameSet != null) { + var packageName = packageNameSet.iterator().next(); + onModifyPackageState(uid, packageName, /* isRemove= */ true); + } else { + Log.wtf(TAG, "clearIsolatedService uid not found"); + } // permissions if (mDest == null) { mIsUpdateDeferred = true; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index d917bffa06e9..bf7f1946531c 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -32,7 +32,6 @@ import static android.Manifest.permission.QUERY_AUDIO_STATE; import static android.Manifest.permission.WRITE_SETTINGS; import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT; import static android.content.Intent.ACTION_PACKAGE_ADDED; -import static android.content.Intent.ACTION_PACKAGE_REMOVED; import static android.content.Intent.EXTRA_ARCHIVAL; import static android.content.Intent.EXTRA_REPLACING; import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP; @@ -3336,11 +3335,25 @@ public class AudioService extends IAudioService.Stub } private int rescaleIndex(int index, int srcStream, int dstStream) { - return rescaleIndex(index, - getVssForStreamOrDefault(srcStream).getMinIndex(), - getVssForStreamOrDefault(srcStream).getMaxIndex(), - getVssForStreamOrDefault(dstStream).getMinIndex(), - getVssForStreamOrDefault(dstStream).getMaxIndex()); + final VolumeStreamState srcVss = getVssForStreamOrDefault(srcStream); + final VolumeStreamState dstVss = getVssForStreamOrDefault(dstStream); + int newIndex = rescaleIndex(index, srcVss.getMinIndex(), srcVss.getMaxIndex(), + dstVss.getMinIndex(), dstVss.getMaxIndex()); + // only apply solution for DTMF stream to make sure that it is not muted when + // re-aliasing to voice call stream. With ringMyCar flag enabled this will be + // automatically solved since we are sending the mute state to APM + // TODO(b/402542630): revisit stream aliasing logic with different min index + // values / mute states + if (!ringMyCar() && dstStream == AudioSystem.STREAM_DTMF + && srcStream == AudioSystem.STREAM_VOICE_CALL + && srcVss.getMinIndex() > dstVss.getMinIndex()) { + newIndex += srcVss.getMinIndex() - dstVss.getMinIndex(); + if (newIndex > dstVss.getMaxIndex()) { + newIndex = dstVss.getMaxIndex(); + } + } + + return newIndex; } private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) { @@ -12929,11 +12942,12 @@ public class AudioService extends IAudioService.Stub ); audioPolicy.registerOnStartTask(() -> { provider.onServiceStart(audioPolicy.getPermissionController()); + sLifecycleLogger.enqueue(new EventLogger.StringEvent( + "Controller start task complete").printLog(ALOGI, TAG)); }); IntentFilter packageUpdateFilter = new IntentFilter(); packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED); - packageUpdateFilter.addAction(ACTION_PACKAGE_REMOVED); packageUpdateFilter.addDataScheme("package"); context.registerReceiverForAllUsers(new BroadcastReceiver() { @@ -12947,9 +12961,6 @@ public class AudioService extends IAudioService.Stub if (ACTION_PACKAGE_ADDED.equals(action)) { audioserverExecutor.execute(() -> provider.onModifyPackageState(uid, pkgName, false /* isRemoved */)); - } else if (ACTION_PACKAGE_REMOVED.equals(action)) { - audioserverExecutor.execute(() -> - provider.onModifyPackageState(uid, pkgName, true /* isRemoved */)); } } }, packageUpdateFilter, null, null); // main thread is fine, since dispatch on executor diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index ac0892b92646..aa985907071f 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -1113,7 +1113,11 @@ public class Vpn { } // Remove always-on VPN if it's not supported. if (!isAlwaysOnPackageSupported(alwaysOnPackage)) { - setAlwaysOnPackage(null, false, null); + // Do not remove the always-on setting due to the restricted ability in safe mode. + // The always-on VPN can then start after the device reboots to normal mode. + if (!mContext.getPackageManager().isSafeMode()) { + setAlwaysOnPackage(null, false, null); + } return false; } // Skip if the service is already established. This isn't bulletproof: it's not bound diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index 7cc178d5ff6c..f5228df3b8b2 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -280,6 +280,11 @@ public class DisplayManagerFlags { Flags::committedStateSeparateEvent ); + private final FlagState mSeparateTimeouts = new FlagState( + Flags.FLAG_SEPARATE_TIMEOUTS, + Flags::separateTimeouts + ); + private final FlagState mDelayImplicitRrRegistrationUntilRrAccessed = new FlagState( Flags.FLAG_DELAY_IMPLICIT_RR_REGISTRATION_UNTIL_RR_ACCESSED, Flags::delayImplicitRrRegistrationUntilRrAccessed @@ -608,6 +613,14 @@ public class DisplayManagerFlags { } /** + * @return {@code true} if the flag for having a separate timeouts for power groups + * is enabled + */ + public boolean isSeparateTimeoutsEnabled() { + return mSeparateTimeouts.isEnabled(); + } + + /** * @return {@code true} if the flag for only explicit subscription for RR changes is enabled */ public boolean isDelayImplicitRrRegistrationUntilRrAccessedEnabled() { @@ -671,6 +684,7 @@ public class DisplayManagerFlags { pw.println(" " + mFramerateOverrideTriggersRrCallbacks); pw.println(" " + mRefreshRateEventForForegroundApps); pw.println(" " + mCommittedStateSeparateEvent); + pw.println(" " + mSeparateTimeouts); pw.println(" " + mDelayImplicitRrRegistrationUntilRrAccessed); } diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index a0064a9f5d1d..007646f6a605 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -509,6 +509,14 @@ flag { } } + +flag { + name: "separate_timeouts" + namespace: "lse_desktop_experience" + description: "Allow separate timeouts for different power groups" + bug: "402356291" +} + flag { name: "delay_implicit_rr_registration_until_rr_accessed" namespace: "display_manager" diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 8f5b831ca0b4..32a61fa2c356 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -79,6 +79,9 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // True by default for all the ARC-enabled ports. private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray(); + @GuardedBy("mLock") + private List<byte[]> mSupportedSads = new ArrayList<>(); + // Whether the System Audio Control feature is enabled or not. True by default. @GuardedBy("mLock") private boolean mSystemAudioControlFeatureEnabled; @@ -858,6 +861,13 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback)); } + void clearSads() { + synchronized (mLock) { + mSupportedSads.clear(); + } + } + + // # Seq 25 void setSystemAudioMode(boolean on) { if (!isSystemAudioControlFeatureEnabled() && on) { @@ -911,13 +921,41 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } @ServiceThreadOnly - void enableArc(List<byte[]> supportedSads) { + void enableArc() { assertRunOnServiceThread(); HdmiLogger.debug("Set Arc Status[old:%b new:true]", mArcEstablished); enableAudioReturnChannel(true); - notifyArcStatusToAudioService(true, supportedSads); + //Ensure mSupportedSads is empty before fetching SADs + synchronized (mLock) { + mSupportedSads.clear(); + notifyArcStatusToAudioService(true, mSupportedSads); + } mArcEstablished = true; + + // Avoid triggering duplicate RequestSadAction events. + // This could lead to unexpected responses from the AVR and cause the TV to receive data + // out of order. The SAD report does not provide information about the order of events. + if (hasAction(RequestSadAction.class)) { + return; + } + + // Send Request SAD to get real SAD instead of default empty + RequestSadAction action = new RequestSadAction( + this, Constants.ADDR_AUDIO_SYSTEM, + new RequestSadAction.RequestSadCallback() { + @Override + public void onRequestSadDone(List<byte[]> supportedSadsDone) { + synchronized (mLock) { + mSupportedSads = supportedSadsDone; + } + notifyArcStatusToAudioService(false, new ArrayList<>()); + synchronized (mLock) { + notifyArcStatusToAudioService(true, mSupportedSads); + } + } + }); + addAndStartAction(action); } @ServiceThreadOnly @@ -928,6 +966,7 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { enableAudioReturnChannel(false); notifyArcStatusToAudioService(false, new ArrayList<>()); mArcEstablished = false; + clearSads(); } /** diff --git a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java index e6abcb958b55..d8dfe44a7394 100644 --- a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java +++ b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java @@ -60,35 +60,20 @@ final class SetArcTransmissionStateAction extends HdmiCecFeatureAction { boolean start() { // Seq #37. if (mEnabled) { - // Avoid triggering duplicate RequestSadAction events. - // This could lead to unexpected responses from the AVR and cause the TV to receive data - // out of order. The SAD report does not provide information about the order of events. - if ((tv().hasAction(RequestSadAction.class))) { - return true; - } - // Request SADs before enabling ARC - RequestSadAction action = new RequestSadAction( - localDevice(), Constants.ADDR_AUDIO_SYSTEM, - new RequestSadAction.RequestSadCallback() { - @Override - public void onRequestSadDone(List<byte[]> supportedSads) { - // Enable ARC status immediately before sending <Report Arc Initiated>. - // If AVR responds with <Feature Abort>, disable ARC status again. - // This is different from spec that says that turns ARC status to - // "Enabled" if <Report ARC Initiated> is acknowledged and no - // <Feature Abort> is received. - // But implemented this way to save the time having to wait for - // <Feature Abort>. - Slog.i(TAG, "Enabling ARC"); - tv().enableArc(supportedSads); - // If succeeds to send <Report ARC Initiated>, wait general timeout to - // check whether there is no <Feature Abort> for <Report ARC Initiated>. - mState = STATE_WAITING_TIMEOUT; - addTimer(mState, HdmiConfig.TIMEOUT_MS); - sendReportArcInitiated(); - } - }); - addAndStartAction(action); + // Enable ARC status immediately before sending <Report Arc Initiated>. + // If AVR responds with <Feature Abort>, disable ARC status again. + // This is different from spec that says that turns ARC status to + // "Enabled" if <Report ARC Initiated> is acknowledged and no + // <Feature Abort> is received. + // But implemented this way to save the time having to wait for + // <Feature Abort>. + Slog.i(TAG, "Enabling ARC"); + tv().enableArc(); + // If succeeds to send <Report ARC Initiated>, wait general timeout to + // check whether there is no <Feature Abort> for <Report ARC Initiated>. + mState = STATE_WAITING_TIMEOUT; + addTimer(mState, HdmiConfig.TIMEOUT_MS); + sendReportArcInitiated(); } else { disableArc(); finish(); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index d9db178e0dc2..6e6d00d62819 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -1230,7 +1230,7 @@ public class InputManagerService extends IInputManager.Stub "registerTabletModeChangedListener()")) { throw new SecurityException("Requires TABLET_MODE_LISTENER permission"); } - Objects.requireNonNull(listener, "event must not be null"); + Objects.requireNonNull(listener, "listener must not be null"); synchronized (mTabletModeLock) { final int callingPid = Binder.getCallingPid(); @@ -1342,7 +1342,7 @@ public class InputManagerService extends IInputManager.Stub @Override public void requestPointerCapture(IBinder inputChannelToken, boolean enabled) { - Objects.requireNonNull(inputChannelToken, "event must not be null"); + Objects.requireNonNull(inputChannelToken, "inputChannelToken must not be null"); mNative.requestPointerCapture(inputChannelToken, enabled); } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 23757757e336..fde9165a84c6 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -5669,11 +5669,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal); } - // TODO(b/352228316): Remove it once IMMIProxy is removed. - InputMethodManagerInternal getLocalService(){ - return mInputMethodManagerInternal; - } - private final class LocalServiceImpl extends InputMethodManagerInternal { @ImfLockFree diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java index 6a72cc7c7779..7d9f2c29f943 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -24,6 +24,7 @@ import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; import android.location.FusedBatchOptions; import android.location.GnssAntennaInfo; +import android.location.GnssAssistance; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementRequest; @@ -35,6 +36,8 @@ import android.location.IGnssStatusListener; import android.location.IGpsGeofenceHardware; import android.location.Location; import android.location.LocationManager; +import android.location.flags.Flags; +import android.location.provider.IGnssAssistanceCallback; import android.location.util.identity.CallerIdentity; import android.os.BatteryStats; import android.os.Binder; @@ -47,12 +50,13 @@ import com.android.internal.app.IBatteryStats; import com.android.server.FgThread; import com.android.server.location.gnss.hal.GnssNative; import com.android.server.location.injector.Injector; +import com.android.server.location.provider.proxy.ProxyGnssAssistanceProvider; import java.io.FileDescriptor; import java.util.List; /** Manages Gnss providers and related Gnss functions for LocationManagerService. */ -public class GnssManagerService { +public class GnssManagerService implements GnssNative.GnssAssistanceCallbacks { public static final String TAG = "GnssManager"; public static final boolean D = Log.isLoggable(TAG, Log.DEBUG); @@ -75,6 +79,8 @@ public class GnssManagerService { private final GnssMetrics mGnssMetrics; + private @Nullable ProxyGnssAssistanceProvider mProxyGnssAssistanceProvider = null; + public GnssManagerService(Context context, Injector injector, GnssNative gnssNative) { mContext = context.createAttributionContext(ATTRIBUTION_ID); mGnssNative = gnssNative; @@ -100,6 +106,16 @@ public class GnssManagerService { /** Called when system is ready. */ public void onSystemReady() { mGnssLocationProvider.onSystemReady(); + + if (Flags.gnssAssistanceInterfaceJni()) { + mProxyGnssAssistanceProvider = + ProxyGnssAssistanceProvider.createAndRegister(mContext); + if (mProxyGnssAssistanceProvider == null) { + Log.e(TAG, "no gnss assistance provider found"); + } else { + mGnssNative.setGnssAssistanceCallbacks(this); + } + } } /** Retrieve the GnssLocationProvider. */ @@ -323,6 +339,29 @@ public class GnssManagerService { } } + @Override + public void onRequestGnssAssistanceInject() { + if (!Flags.gnssAssistanceInterfaceJni()) { + return; + } + if (mProxyGnssAssistanceProvider == null) { + Log.e(TAG, "ProxyGnssAssistanceProvider is null"); + return; + } + mProxyGnssAssistanceProvider.request(new IGnssAssistanceCallback.Stub() { + @Override + public void onError() { + Log.e(TAG, "GnssAssistanceCallback.onError"); + } + + @Override + public void onResult(GnssAssistance gnssAssistance) { + Log.d(TAG, "GnssAssistanceCallback.onResult"); + mGnssNative.injectGnssAssistance(gnssAssistance); + } + }); + } + private class GnssCapabilitiesHalModule implements GnssNative.BaseCallbacks { GnssCapabilitiesHalModule(GnssNative gnssNative) { diff --git a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java index c79a21a7eea8..7fd400ec8ac9 100644 --- a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java @@ -23,6 +23,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.location.GnssAntennaInfo; +import android.location.GnssAssistance; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementsEvent; @@ -30,6 +31,7 @@ import android.location.GnssNavigationMessage; import android.location.GnssSignalType; import android.location.GnssStatus; import android.location.Location; +import android.location.flags.Flags; import android.os.Binder; import android.os.Handler; import android.os.SystemClock; @@ -275,6 +277,12 @@ public class GnssNative { void onRequestPsdsDownload(int psdsType); } + /** Callbacks for HAL requesting GNSS assistance. */ + public interface GnssAssistanceCallbacks { + /** On request GnssAssistance injection. */ + void onRequestGnssAssistanceInject(); + } + /** Callbacks for AGPS functionality. */ public interface AGpsCallbacks { @@ -400,6 +408,7 @@ public class GnssNative { private TimeCallbacks mTimeCallbacks; private LocationRequestCallbacks mLocationRequestCallbacks; private PsdsCallbacks mPsdsCallbacks; + private @Nullable GnssAssistanceCallbacks mGnssAssistanceCallbacks; private AGpsCallbacks mAGpsCallbacks; private NotificationCallbacks mNotificationCallbacks; @@ -504,6 +513,15 @@ public class GnssNative { mNotificationCallbacks = Objects.requireNonNull(callbacks); } + /** Sets GnssAssistanceCallbacks. */ + public void setGnssAssistanceCallbacks(GnssAssistanceCallbacks callbacks) { + if (!Flags.gnssAssistanceInterfaceJni()) { + return; + } + Preconditions.checkState(mGnssAssistanceCallbacks == null); + mGnssAssistanceCallbacks = Objects.requireNonNull(callbacks); + } + /** * Registers with the HAL and allows callbacks to begin. Once registered with the native HAL, * no more callbacks can be added or set. Must only be called once. @@ -1053,6 +1071,17 @@ public class GnssNative { mGnssHal.injectNiSuplMessageData(data, length, slotIndex); } + /** + * Injects GNSS assistance data into the GNSS HAL. + */ + public void injectGnssAssistance(GnssAssistance assistance) { + if (!Flags.gnssAssistanceInterfaceJni()) { + return; + } + Preconditions.checkState(mRegistered); + mGnssHal.injectGnssAssistance(assistance); + } + @NativeEntryPoint void reportGnssServiceDied() { // Not necessary to clear (and restore) binder identity since it runs on another thread. @@ -1269,6 +1298,15 @@ public class GnssNative { } @NativeEntryPoint + void gnssAssistanceInjectRequest() { + if (!Flags.gnssAssistanceInterfaceJni() || mGnssAssistanceCallbacks == null) { + return; + } + Binder.withCleanCallingIdentity( + () -> mGnssAssistanceCallbacks.onRequestGnssAssistanceInject()); + } + + @NativeEntryPoint void reportGeofenceTransition(int geofenceId, Location location, int transition, long transitionTimestamp) { Binder.withCleanCallingIdentity( @@ -1569,6 +1607,10 @@ public class GnssNative { protected void injectNiSuplMessageData(byte[] data, int length, int slotIndex) { native_inject_ni_supl_message_data(data, length, slotIndex); } + + protected void injectGnssAssistance(GnssAssistance gnssAssistance) { + native_inject_gnss_assistance(gnssAssistance); + } } // basic APIs @@ -1718,4 +1760,7 @@ public class GnssNative { private static native boolean native_supports_psds(); private static native void native_inject_psds_data(byte[] data, int length, int psdsType); + + // GNSS Assistance APIs + private static native void native_inject_gnss_assistance(GnssAssistance gnssAssistance); } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 42d0a5c4757a..a8190269450a 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -31,7 +31,6 @@ import static android.content.Intent.ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTO import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_SYSTEM; -import static android.security.Flags.reportPrimaryAuthAttempts; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN; @@ -2483,11 +2482,8 @@ public class LockSettingsService extends ILockSettings.Stub { requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); } } - if (reportPrimaryAuthAttempts()) { - final boolean success = - response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK; - notifyLockSettingsStateListeners(success, userId); - } + final boolean success = response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK; + notifyLockSettingsStateListeners(success, userId); return response; } diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java index ad108f64ffe3..9a09807d52d7 100644 --- a/services/core/java/com/android/server/media/quality/MediaQualityService.java +++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java @@ -371,12 +371,8 @@ public class MediaQualityService extends SystemService { PictureParameter[] pictureParameters = MediaQualityUtils .convertPersistableBundleToPictureParameterList(params); - PersistableBundle vendorPictureParameters = params - .getPersistableBundle(BaseParameters.VENDOR_PARAMETERS); Parcel parcel = Parcel.obtain(); - if (vendorPictureParameters != null) { - setVendorPictureParameters(pp, parcel, vendorPictureParameters); - } + setVendorPictureParameters(pp, parcel, params); pp.pictureParameters = pictureParameters; @@ -1429,11 +1425,9 @@ public class MediaQualityService extends SystemService { MediaQualityUtils.convertPersistableBundleToPictureParameterList( params); - PersistableBundle vendorPictureParameters = params - .getPersistableBundle(BaseParameters.VENDOR_PARAMETERS); Parcel parcel = Parcel.obtain(); - if (vendorPictureParameters != null) { - setVendorPictureParameters(pictureParameters, parcel, vendorPictureParameters); + if (params != null) { + setVendorPictureParameters(pictureParameters, parcel, params); } android.hardware.tv.mediaquality.PictureProfile toReturn = diff --git a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java index 303c96750098..cf8b703a2641 100644 --- a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java +++ b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java @@ -373,323 +373,403 @@ public final class MediaQualityUtils { if (params.containsKey(PictureQuality.PARAMETER_BRIGHTNESS)) { pictureParams.add(PictureParameter.brightness(params.getLong( PictureQuality.PARAMETER_BRIGHTNESS))); + params.remove(PictureQuality.PARAMETER_BRIGHTNESS); } if (params.containsKey(PictureQuality.PARAMETER_CONTRAST)) { pictureParams.add(PictureParameter.contrast(params.getInt( PictureQuality.PARAMETER_CONTRAST))); + params.remove(PictureQuality.PARAMETER_CONTRAST); } if (params.containsKey(PictureQuality.PARAMETER_SHARPNESS)) { pictureParams.add(PictureParameter.sharpness(params.getInt( PictureQuality.PARAMETER_SHARPNESS))); + params.remove(PictureQuality.PARAMETER_SHARPNESS); } if (params.containsKey(PictureQuality.PARAMETER_SATURATION)) { pictureParams.add(PictureParameter.saturation(params.getInt( PictureQuality.PARAMETER_SATURATION))); + params.remove(PictureQuality.PARAMETER_SATURATION); } if (params.containsKey(PictureQuality.PARAMETER_HUE)) { pictureParams.add(PictureParameter.hue(params.getInt( PictureQuality.PARAMETER_HUE))); + params.remove(PictureQuality.PARAMETER_HUE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS)) { pictureParams.add(PictureParameter.colorTunerBrightness(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION)) { pictureParams.add(PictureParameter.colorTunerSaturation(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE)) { pictureParams.add(PictureParameter.colorTunerHue(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET)) { pictureParams.add(PictureParameter.colorTunerRedOffset(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET)) { pictureParams.add(PictureParameter.colorTunerGreenOffset(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET)) { pictureParams.add(PictureParameter.colorTunerBlueOffset(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)) { pictureParams.add(PictureParameter.colorTunerRedGain(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)) { pictureParams.add(PictureParameter.colorTunerGreenGain(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)) { pictureParams.add(PictureParameter.colorTunerBlueGain(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_NOISE_REDUCTION)) { pictureParams.add(PictureParameter.noiseReduction( (byte) params.getInt(PictureQuality.PARAMETER_NOISE_REDUCTION))); + params.remove(PictureQuality.PARAMETER_NOISE_REDUCTION); } if (params.containsKey(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION)) { pictureParams.add(PictureParameter.mpegNoiseReduction( (byte) params.getInt(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION))); + params.remove(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION); } if (params.containsKey(PictureQuality.PARAMETER_FLESH_TONE)) { pictureParams.add(PictureParameter.fleshTone( (byte) params.getInt(PictureQuality.PARAMETER_FLESH_TONE))); + params.remove(PictureQuality.PARAMETER_FLESH_TONE); } if (params.containsKey(PictureQuality.PARAMETER_DECONTOUR)) { pictureParams.add(PictureParameter.deContour( (byte) params.getInt(PictureQuality.PARAMETER_DECONTOUR))); + params.remove(PictureQuality.PARAMETER_DECONTOUR); } if (params.containsKey(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL)) { pictureParams.add(PictureParameter.dynamicLumaControl( (byte) params.getInt(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL))); + params.remove(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL); } if (params.containsKey(PictureQuality.PARAMETER_FILM_MODE)) { pictureParams.add(PictureParameter.filmMode(params.getBoolean( PictureQuality.PARAMETER_FILM_MODE))); + params.remove(PictureQuality.PARAMETER_FILM_MODE); } if (params.containsKey(PictureQuality.PARAMETER_BLUE_STRETCH)) { pictureParams.add(PictureParameter.blueStretch(params.getBoolean( PictureQuality.PARAMETER_BLUE_STRETCH))); + params.remove(PictureQuality.PARAMETER_BLUE_STRETCH); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNE)) { pictureParams.add(PictureParameter.colorTune(params.getBoolean( PictureQuality.PARAMETER_COLOR_TUNE))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE)) { pictureParams.add(PictureParameter.colorTemperature( (byte) params.getInt( PictureQuality.PARAMETER_COLOR_TEMPERATURE))); + params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE); } if (params.containsKey(PictureQuality.PARAMETER_GLOBAL_DIMMING)) { pictureParams.add(PictureParameter.globeDimming(params.getBoolean( PictureQuality.PARAMETER_GLOBAL_DIMMING))); + params.remove(PictureQuality.PARAMETER_GLOBAL_DIMMING); } if (params.containsKey(PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED)) { pictureParams.add(PictureParameter.autoPictureQualityEnabled(params.getBoolean( PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED))); + params.remove(PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED); } if (params.containsKey(PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED)) { pictureParams.add(PictureParameter.autoSuperResolutionEnabled(params.getBoolean( PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED))); + params.remove(PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)) { pictureParams.add(PictureParameter.colorTemperatureRedGain(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)) { pictureParams.add(PictureParameter.colorTemperatureGreenGain(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)) { pictureParams.add(PictureParameter.colorTemperatureBlueGain(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_LEVEL_RANGE)) { pictureParams.add(PictureParameter.levelRange( (byte) params.getInt(PictureQuality.PARAMETER_LEVEL_RANGE))); + params.remove(PictureQuality.PARAMETER_LEVEL_RANGE); } if (params.containsKey(PictureQuality.PARAMETER_GAMUT_MAPPING)) { pictureParams.add(PictureParameter.gamutMapping(params.getBoolean( PictureQuality.PARAMETER_GAMUT_MAPPING))); + params.remove(PictureQuality.PARAMETER_GAMUT_MAPPING); } if (params.containsKey(PictureQuality.PARAMETER_PC_MODE)) { pictureParams.add(PictureParameter.pcMode(params.getBoolean( PictureQuality.PARAMETER_PC_MODE))); + params.remove(PictureQuality.PARAMETER_PC_MODE); } if (params.containsKey(PictureQuality.PARAMETER_LOW_LATENCY)) { pictureParams.add(PictureParameter.lowLatency(params.getBoolean( PictureQuality.PARAMETER_LOW_LATENCY))); + params.remove(PictureQuality.PARAMETER_LOW_LATENCY); } if (params.containsKey(PictureQuality.PARAMETER_VRR)) { pictureParams.add(PictureParameter.vrr(params.getBoolean( PictureQuality.PARAMETER_VRR))); + params.remove(PictureQuality.PARAMETER_VRR); } if (params.containsKey(PictureQuality.PARAMETER_CVRR)) { pictureParams.add(PictureParameter.cvrr(params.getBoolean( PictureQuality.PARAMETER_CVRR))); + params.remove(PictureQuality.PARAMETER_CVRR); } if (params.containsKey(PictureQuality.PARAMETER_HDMI_RGB_RANGE)) { pictureParams.add(PictureParameter.hdmiRgbRange( (byte) params.getInt(PictureQuality.PARAMETER_HDMI_RGB_RANGE))); + params.remove(PictureQuality.PARAMETER_HDMI_RGB_RANGE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_SPACE)) { pictureParams.add(PictureParameter.colorSpace( (byte) params.getInt(PictureQuality.PARAMETER_COLOR_SPACE))); + params.remove(PictureQuality.PARAMETER_COLOR_SPACE); } if (params.containsKey(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_NITS)) { pictureParams.add(PictureParameter.panelInitMaxLuminceNits( params.getInt(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_NITS))); + params.remove(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_NITS); } if (params.containsKey(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_VALID)) { pictureParams.add(PictureParameter.panelInitMaxLuminceValid( params.getBoolean(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_VALID))); + params.remove(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_VALID); } if (params.containsKey(PictureQuality.PARAMETER_GAMMA)) { pictureParams.add(PictureParameter.gamma( (byte) params.getInt(PictureQuality.PARAMETER_GAMMA))); + params.remove(PictureQuality.PARAMETER_GAMMA); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE_RED_OFFSET)) { pictureParams.add(PictureParameter.colorTemperatureRedOffset(params.getInt( PictureQuality.PARAMETER_COLOR_TEMPERATURE_RED_OFFSET))); + params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE_RED_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE_GREEN_OFFSET)) { pictureParams.add(PictureParameter.colorTemperatureGreenOffset(params.getInt( PictureQuality.PARAMETER_COLOR_TEMPERATURE_GREEN_OFFSET))); + params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE_GREEN_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE_BLUE_OFFSET)) { pictureParams.add(PictureParameter.colorTemperatureBlueOffset(params.getInt( PictureQuality.PARAMETER_COLOR_TEMPERATURE_BLUE_OFFSET))); + params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE_BLUE_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_ELEVEN_POINT_RED)) { pictureParams.add(PictureParameter.elevenPointRed(params.getIntArray( PictureQuality.PARAMETER_ELEVEN_POINT_RED))); + params.remove(PictureQuality.PARAMETER_ELEVEN_POINT_RED); } if (params.containsKey(PictureQuality.PARAMETER_ELEVEN_POINT_GREEN)) { pictureParams.add(PictureParameter.elevenPointGreen(params.getIntArray( PictureQuality.PARAMETER_ELEVEN_POINT_GREEN))); + params.remove(PictureQuality.PARAMETER_ELEVEN_POINT_GREEN); } if (params.containsKey(PictureQuality.PARAMETER_ELEVEN_POINT_BLUE)) { pictureParams.add(PictureParameter.elevenPointBlue(params.getIntArray( PictureQuality.PARAMETER_ELEVEN_POINT_BLUE))); + params.remove(PictureQuality.PARAMETER_ELEVEN_POINT_BLUE); } if (params.containsKey(PictureQuality.PARAMETER_LOW_BLUE_LIGHT)) { pictureParams.add(PictureParameter.lowBlueLight( (byte) params.getInt(PictureQuality.PARAMETER_LOW_BLUE_LIGHT))); + params.remove(PictureQuality.PARAMETER_LOW_BLUE_LIGHT); } if (params.containsKey(PictureQuality.PARAMETER_LD_MODE)) { pictureParams.add(PictureParameter.LdMode( (byte) params.getInt(PictureQuality.PARAMETER_LD_MODE))); + params.remove(PictureQuality.PARAMETER_LD_MODE); } if (params.containsKey(PictureQuality.PARAMETER_OSD_RED_GAIN)) { pictureParams.add(PictureParameter.osdRedGain(params.getInt( PictureQuality.PARAMETER_OSD_RED_GAIN))); + params.remove(PictureQuality.PARAMETER_OSD_RED_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_OSD_GREEN_GAIN)) { pictureParams.add(PictureParameter.osdGreenGain(params.getInt( PictureQuality.PARAMETER_OSD_GREEN_GAIN))); + params.remove(PictureQuality.PARAMETER_OSD_GREEN_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_OSD_BLUE_GAIN)) { pictureParams.add(PictureParameter.osdBlueGain(params.getInt( PictureQuality.PARAMETER_OSD_BLUE_GAIN))); + params.remove(PictureQuality.PARAMETER_OSD_BLUE_GAIN); } if (params.containsKey(PictureQuality.PARAMETER_OSD_RED_OFFSET)) { pictureParams.add(PictureParameter.osdRedOffset(params.getInt( PictureQuality.PARAMETER_OSD_RED_OFFSET))); + params.remove(PictureQuality.PARAMETER_OSD_RED_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_OSD_GREEN_OFFSET)) { pictureParams.add(PictureParameter.osdGreenOffset(params.getInt( PictureQuality.PARAMETER_OSD_GREEN_OFFSET))); + params.remove(PictureQuality.PARAMETER_OSD_GREEN_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_OSD_BLUE_OFFSET)) { pictureParams.add(PictureParameter.osdBlueOffset(params.getInt( PictureQuality.PARAMETER_OSD_BLUE_OFFSET))); + params.remove(PictureQuality.PARAMETER_OSD_BLUE_OFFSET); } if (params.containsKey(PictureQuality.PARAMETER_OSD_HUE)) { pictureParams.add(PictureParameter.osdHue(params.getInt( PictureQuality.PARAMETER_OSD_HUE))); + params.remove(PictureQuality.PARAMETER_OSD_HUE); } if (params.containsKey(PictureQuality.PARAMETER_OSD_SATURATION)) { pictureParams.add(PictureParameter.osdSaturation(params.getInt( PictureQuality.PARAMETER_OSD_SATURATION))); + params.remove(PictureQuality.PARAMETER_OSD_SATURATION); } if (params.containsKey(PictureQuality.PARAMETER_OSD_CONTRAST)) { pictureParams.add(PictureParameter.osdContrast(params.getInt( PictureQuality.PARAMETER_OSD_CONTRAST))); + params.remove(PictureQuality.PARAMETER_OSD_CONTRAST); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SWITCH)) { pictureParams.add(PictureParameter.colorTunerSwitch(params.getBoolean( PictureQuality.PARAMETER_COLOR_TUNER_SWITCH))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SWITCH); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_RED)) { pictureParams.add(PictureParameter.colorTunerHueRed(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_RED))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_RED); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_GREEN)) { pictureParams.add(PictureParameter.colorTunerHueGreen(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_GREEN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_GREEN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_BLUE)) { pictureParams.add(PictureParameter.colorTunerHueBlue(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_BLUE))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_BLUE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_CYAN)) { pictureParams.add(PictureParameter.colorTunerHueCyan(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_CYAN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_CYAN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_MAGENTA)) { pictureParams.add(PictureParameter.colorTunerHueMagenta(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_MAGENTA))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_MAGENTA); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_YELLOW)) { pictureParams.add(PictureParameter.colorTunerHueYellow(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_YELLOW))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_YELLOW); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_FLESH)) { pictureParams.add(PictureParameter.colorTunerHueFlesh(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_HUE_FLESH))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_FLESH); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_RED)) { pictureParams.add(PictureParameter.colorTunerSaturationRed(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_RED))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_RED); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_GREEN)) { pictureParams.add(PictureParameter.colorTunerSaturationGreen(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_GREEN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_GREEN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_BLUE)) { pictureParams.add(PictureParameter.colorTunerSaturationBlue(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_BLUE))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_BLUE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_CYAN)) { pictureParams.add(PictureParameter.colorTunerSaturationCyan(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_CYAN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_CYAN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_MAGENTA)) { pictureParams.add(PictureParameter.colorTunerSaturationMagenta(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_MAGENTA))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_MAGENTA); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_YELLOW)) { pictureParams.add(PictureParameter.colorTunerSaturationYellow(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_YELLOW))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_YELLOW); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_FLESH)) { pictureParams.add(PictureParameter.colorTunerSaturationFlesh(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_FLESH))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_FLESH); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_RED)) { pictureParams.add(PictureParameter.colorTunerLuminanceRed(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_RED))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_RED); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_GREEN)) { pictureParams.add(PictureParameter.colorTunerLuminanceGreen(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_GREEN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_GREEN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_BLUE)) { pictureParams.add(PictureParameter.colorTunerLuminanceBlue(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_BLUE))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_BLUE); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_CYAN)) { pictureParams.add(PictureParameter.colorTunerLuminanceCyan(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_CYAN))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_CYAN); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_MAGENTA)) { pictureParams.add(PictureParameter.colorTunerLuminanceMagenta(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_MAGENTA))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_MAGENTA); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_YELLOW)) { pictureParams.add(PictureParameter.colorTunerLuminanceYellow(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_YELLOW))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_YELLOW); } if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_FLESH)) { pictureParams.add(PictureParameter.colorTunerLuminanceFlesh(params.getInt( PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_FLESH))); + params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_FLESH); } if (params.containsKey(PictureQuality.PARAMETER_PICTURE_QUALITY_EVENT_TYPE)) { pictureParams.add(PictureParameter.pictureQualityEventType( (byte) params.getInt(PictureQuality.PARAMETER_PICTURE_QUALITY_EVENT_TYPE))); + params.remove(PictureQuality.PARAMETER_PICTURE_QUALITY_EVENT_TYPE); } return pictureParams.toArray(new PictureParameter[0]); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7a544cf1c26c..78554bdcf6aa 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -764,6 +764,8 @@ public class NotificationManagerService extends SystemService { private long mLastOverRateLogTime; private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE; + private boolean mRedactOtpNotifications = true; + private NotificationHistoryManager mHistoryManager; protected SnoozeHelper mSnoozeHelper; private TimeToLiveHelper mTtlHelper; @@ -2410,6 +2412,8 @@ public class NotificationManagerService extends SystemService { = Secure.getUriFor(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); private final Uri SHOW_NOTIFICATION_SNOOZE = Secure.getUriFor(Secure.SHOW_NOTIFICATION_SNOOZE); + private final Uri REDACT_OTP_NOTIFICATIONS = Settings.Global.getUriFor( + Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); SettingsObserver(Handler handler) { super(handler); @@ -2435,6 +2439,8 @@ public class NotificationManagerService extends SystemService { resolver.registerContentObserver(SHOW_NOTIFICATION_SNOOZE, false, this, USER_ALL); + resolver.registerContentObserver(REDACT_OTP_NOTIFICATIONS, + false, this, USER_ALL); update(null); } @@ -2481,6 +2487,10 @@ public class NotificationManagerService extends SystemService { unsnoozeAll(); } } + if (REDACT_OTP_NOTIFICATIONS.equals(uri)) { + mRedactOtpNotifications = Settings.Global.getInt(resolver, + Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS, 1) != 0; + } } public void update(Uri uri, int userId) { @@ -6163,10 +6173,15 @@ public class NotificationManagerService extends SystemService { } @Override - public Map<String, AutomaticZenRule> getAutomaticZenRules() { + public ParceledListSlice getAutomaticZenRules() { int callingUid = Binder.getCallingUid(); enforcePolicyAccess(callingUid, "getAutomaticZenRules"); - return mZenModeHelper.getAutomaticZenRules(getCallingZenUser(), callingUid); + List<AutomaticZenRule.AzrWithId> ruleList = new ArrayList<>(); + for (Map.Entry<String, AutomaticZenRule> rule : mZenModeHelper.getAutomaticZenRules( + getCallingZenUser(), callingUid).entrySet()) { + ruleList.add(new AutomaticZenRule.AzrWithId(rule.getKey(), rule.getValue())); + } + return new ParceledListSlice<>(ruleList); } @Override @@ -13453,13 +13468,13 @@ public class NotificationManagerService extends SystemService { StatusBarNotification oldRedactedSbn = null; boolean isNewSensitive = hasSensitiveContent(r); boolean isOldSensitive = hasSensitiveContent(old); + boolean redactionEnabled = redactSensitiveNotificationsFromUntrustedListeners() + && mRedactOtpNotifications; for (final ManagedServiceInfo info : getServices()) { boolean isTrusted = isUidTrusted(info.uid); - boolean sendRedacted = redactSensitiveNotificationsFromUntrustedListeners() - && isNewSensitive && !isTrusted; - boolean sendOldRedacted = redactSensitiveNotificationsFromUntrustedListeners() - && isOldSensitive && !isTrusted; + boolean sendRedacted = redactionEnabled && isNewSensitive && !isTrusted; + boolean sendOldRedacted = redactionEnabled && isOldSensitive && !isTrusted; boolean sbnVisible = isVisibleToListener(sbn, r.getNotificationType(), info); boolean oldSbnVisible = (oldSbn != null) && isVisibleToListener(oldSbn, old.getNotificationType(), info); diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java index bc987ed21251..ffc7c7b26ebd 100644 --- a/services/core/java/com/android/server/notification/NotificationShellCmd.java +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -45,6 +45,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ShellCommand; import android.os.UserHandle; +import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.text.TextUtils; @@ -81,6 +82,7 @@ public class NotificationShellCmd extends ShellCommand { + " snooze --for <msec> <notification-key>\n" + " unsnooze <notification-key>\n" + " set_exempt_th_force_grouping [true|false]\n" + + " redact_otp_from_untrusted_listeners [true|false]\n" ; private static final String NOTIFY_USAGE = @@ -431,6 +433,14 @@ public class NotificationShellCmd extends ShellCommand { mDirectService.setTestHarnessExempted(exemptTestHarnessFromForceGrouping); break; } + case "redact_otp_from_untrusted_listeners": { + String arg = getNextArgRequired(); + final int allow = "true".equals(arg) || "1".equals(arg) ? 1 : 0; + Settings.Global.putInt(mDirectService.getContext().getContentResolver(), + Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS, + allow); + break; + } default: return handleDefaultCommands(cmd); } diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java index 524252c1469f..e71588168972 100644 --- a/services/core/java/com/android/server/pm/ProtectedPackages.java +++ b/services/core/java/com/android/server/pm/ProtectedPackages.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.os.UserHandle; +import android.text.TextUtils; import android.util.ArraySet; import android.util.SparseArray; @@ -27,6 +28,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import java.util.List; +import java.util.Objects; import java.util.Set; /** @@ -164,4 +166,13 @@ public class ProtectedPackages { return hasDeviceOwnerOrProfileOwner(userId, packageName) || isProtectedPackage(userId, packageName); } + + /** + * Returns {@code true} if a given package is the device provisioning package. Otherwise, + * returns {@code false}. + */ + public synchronized boolean isDeviceProvisioningPackage(String packageName) { + return !TextUtils.isEmpty(mDeviceProvisioningPackage) && Objects.equals( + mDeviceProvisioningPackage, packageName); + } } diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING index 1fda4782fc86..92e8eb9cd1bb 100644 --- a/services/core/java/com/android/server/pm/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/TEST_MAPPING @@ -133,6 +133,38 @@ ] }, { + "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases", + "file_patterns": [ + "core/java/.*Install.*", + "services/core/.*Install.*", + "services/core/java/com/android/server/pm/.*" + ], + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { + "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases", + "file_patterns": [ + "core/java/.*Install.*", + "services/core/.*Install.*", + "services/core/java/com/android/server/pm/.*" + ], + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { "name": "CtsPackageInstallerCUJMultiUsersTestCases", "file_patterns": [ "core/java/.*Install.*", @@ -288,6 +320,38 @@ ] }, { + "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases", + "file_patterns": [ + "core/java/.*Install.*", + "services/core/.*Install.*", + "services/core/java/com/android/server/pm/.*" + ], + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { + "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases", + "file_patterns": [ + "core/java/.*Install.*", + "services/core/.*Install.*", + "services/core/java/com/android/server/pm/.*" + ], + "options":[ + { + "exclude-annotation":"androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation":"org.junit.Ignore" + } + ] + }, + { "name": "CtsPackageInstallerCUJMultiUsersTestCases", "file_patterns": [ "core/java/.*Install.*", diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 092ec8ef4a8a..233b577e1c61 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1078,7 +1078,7 @@ public class UserManagerService extends IUserManager.Stub { mUserVisibilityMediator = new UserVisibilityMediator(mHandler); mUserDataPreparer = userDataPreparer; mUserTypes = UserTypeFactory.getUserTypes(); - invalidateOwnerNameIfNecessary(context.getResources(), true /* forceUpdate */); + invalidateOwnerNameIfNecessary(getContextResources(), true /* forceUpdate */); synchronized (mPackagesLock) { mUsersDir = new File(dataDir, USER_INFO_DIR); mUsersDir.mkdirs(); @@ -1184,6 +1184,15 @@ public class UserManagerService extends IUserManager.Stub { && android.multiuser.Flags.enablePrivateSpaceFeatures(); } + private Resources getSystemResources() { + return android.multiuser.Flags.useUnifiedResources() + ? getContextResources() : Resources.getSystem(); + } + + private Resources getContextResources() { + return mContext.getResources(); + } + /** * This method retrieves the {@link UserManagerInternal} only for the purpose of * PackageManagerService construction. @@ -1223,7 +1232,7 @@ public class UserManagerService extends IUserManager.Stub { // Avoid marking pre-created users for removal. return; } - if (ui.lastLoggedInTime == 0 && ui.isGuest() && Resources.getSystem().getBoolean( + if (ui.lastLoggedInTime == 0 && ui.isGuest() && getSystemResources().getBoolean( com.android.internal.R.bool.config_guestUserAutoCreated)) { // Avoid marking auto-created but not-yet-logged-in guest user for removal. Because a // new one will be created anyway, and this one doesn't have any personal data in it yet @@ -1402,7 +1411,7 @@ public class UserManagerService extends IUserManager.Stub { } if (isHeadlessSystemUserMode()) { - final int bootStrategy = mContext.getResources() + final int bootStrategy = getContextResources() .getInteger(com.android.internal.R.integer.config_hsumBootStrategy); switch (bootStrategy) { case BOOT_TO_PREVIOUS_OR_FIRST_SWITCHABLE_USER: @@ -2983,7 +2992,7 @@ public class UserManagerService extends IUserManager.Stub { boolean isUserSwitcherEnabled(@UserIdInt int userId) { boolean multiUserSettingOn = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.USER_SWITCHER_ENABLED, - Resources.getSystem().getBoolean(com.android.internal + getSystemResources().getBoolean(com.android.internal .R.bool.config_showUserSwitcherByDefault) ? 1 : 0) != 0; return UserManager.supportsMultipleUsers() @@ -4672,7 +4681,7 @@ public class UserManagerService extends IUserManager.Stub { UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM); if ("Primary".equals(userData.info.name)) { userData.info.name = - mContext.getResources().getString(com.android.internal.R.string.owner_name); + getContextResources().getString(com.android.internal.R.string.owner_name); userIdsToWrite.add(userData.info.id); } userVersion = 1; @@ -5002,7 +5011,7 @@ public class UserManagerService extends IUserManager.Stub { final Bundle restrictions = new Bundle(); try { - final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray( + final String[] defaultFirstUserRestrictions = getContextResources().getStringArray( com.android.internal.R.array.config_defaultFirstUserRestrictions); for (String userRestriction : defaultFirstUserRestrictions) { if (UserRestrictionsUtils.isValidRestriction(userRestriction)) { @@ -6178,7 +6187,7 @@ public class UserManagerService extends IUserManager.Stub { // If the user switch hasn't been explicitly toggled on or off by the user, turn it on. if (android.provider.Settings.Global.getString(mContext.getContentResolver(), android.provider.Settings.Global.USER_SWITCHER_ENABLED) == null) { - if (Resources.getSystem().getBoolean( + if (getSystemResources().getBoolean( com.android.internal.R.bool.config_enableUserSwitcherUponUserCreation)) { android.provider.Settings.Global.putInt(mContext.getContentResolver(), android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1); @@ -7490,7 +7499,6 @@ public class UserManagerService extends IUserManager.Stub { final long now = System.currentTimeMillis(); final long nowRealtime = SystemClock.elapsedRealtime(); final StringBuilder sb = new StringBuilder(); - final Resources resources = Resources.getSystem(); if (args != null && args.length > 0) { switch (args[0]) { @@ -7573,13 +7581,14 @@ public class UserManagerService extends IUserManager.Stub { pw.println(); int effectiveMaxSupportedUsers = UserManager.getMaxSupportedUsers(); pw.print(" Max users: " + effectiveMaxSupportedUsers); - int defaultMaxSupportedUsers = resources.getInteger(R.integer.config_multiuserMaximumUsers); + int defaultMaxSupportedUsers = getSystemResources() + .getInteger(R.integer.config_multiuserMaximumUsers); if (effectiveMaxSupportedUsers != defaultMaxSupportedUsers) { pw.print(" (built-in value: " + defaultMaxSupportedUsers + ")"); } pw.println(" (limit reached: " + isUserLimitReached() + ")"); pw.println(" Supports switchable users: " + UserManager.supportsMultipleUsers()); - pw.println(" All guests ephemeral: " + resources.getBoolean( + pw.println(" All guests ephemeral: " + getSystemResources().getBoolean( com.android.internal.R.bool.config_guestUserEphemeral)); pw.println(" Force ephemeral users: " + mForceEphemeralUsers); final boolean isHeadlessSystemUserMode = isHeadlessSystemUserMode(); @@ -7594,7 +7603,7 @@ public class UserManagerService extends IUserManager.Stub { } } if (isHeadlessSystemUserMode) { - pw.println(" Can switch to headless system user: " + resources + pw.println(" Can switch to headless system user: " + getSystemResources() .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser)); } pw.println(" User version: " + mUserVersion); @@ -8536,8 +8545,7 @@ public class UserManagerService extends IUserManager.Stub { * or downgraded to non-admin status. */ public boolean isMainUserPermanentAdmin() { - return Resources.getSystem() - .getBoolean(R.bool.config_isMainUserPermanentAdmin); + return getSystemResources().getBoolean(R.bool.config_isMainUserPermanentAdmin); } /** @@ -8546,8 +8554,7 @@ public class UserManagerService extends IUserManager.Stub { * it is not a full user. */ public boolean canSwitchToHeadlessSystemUser() { - return Resources.getSystem() - .getBoolean(R.bool.config_canSwitchToHeadlessSystemUser); + return getSystemResources().getBoolean(R.bool.config_canSwitchToHeadlessSystemUser); } /** diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index c31c287017c3..4ffdb1124571 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -235,15 +235,12 @@ public final class PermissionPolicyService extends SystemService { this::synchronizeUidPermissionsAndAppOpsAsync); mAppOpsCallback = new IAppOpsCallback.Stub() { - public void opChanged(int op, int uid, @Nullable String packageName, - String persistentDeviceId) { + public void opChanged(int op, int uid, String packageName, String persistentDeviceId) { if (!Objects.equals(persistentDeviceId, - VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) { + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) || uid < 0) { return; } - if (packageName != null) { - synchronizeUidPermissionsAndAppOpsAsync(uid); - } + synchronizeUidPermissionsAndAppOpsAsync(uid); resetAppOpPermissionsIfNotRequestedForUidAsync(uid); } }; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 3230e891db55..38d458767015 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -5966,7 +5966,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { long whenNanos, int policyFlags) { if ((policyFlags & FLAG_WAKE) != 0) { if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source, - action == MotionEvent.ACTION_DOWN)) { + action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) { // Woke up. Pass motion events to user. return ACTION_PASS_TO_USER; } @@ -5981,7 +5981,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // wake up in this case. if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) { if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source, - action == MotionEvent.ACTION_DOWN)) { + action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) { // Woke up. Pass motion events to user. return ACTION_PASS_TO_USER; } diff --git a/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java b/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java index 04dbd1fea5d6..0b5ec6e4f495 100644 --- a/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java +++ b/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java @@ -149,16 +149,22 @@ class WindowWakeUpPolicy { * @param displayId the id of the display to wake. * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}. * @param isDown {@code true} if the event's action is {@link MotionEvent#ACTION_DOWN}. + * @param deviceGoingToSleep {@code true} if the device is in the middle of going to sleep. This + * will be {@code false} if the device is currently fully awake or is fully asleep + * (i.e. not trying to go to sleep) * @return {@code true} if the policy allows the requested wake up and the request has been * executed; {@code false} otherwise. */ - boolean wakeUpFromMotion(int displayId, long eventTime, int source, boolean isDown) { + boolean wakeUpFromMotion( + int displayId, long eventTime, int source, boolean isDown, + boolean deviceGoingToSleep) { if (!canWakeUp(mAllowTheaterModeWakeFromMotion)) { if (DEBUG) Slog.d(TAG, "Unable to wake up from motion."); return false; } if (mInputWakeUpDelegate != null - && mInputWakeUpDelegate.wakeUpFromMotion(eventTime, source, isDown)) { + && mInputWakeUpDelegate.wakeUpFromMotion( + eventTime, source, isDown, deviceGoingToSleep)) { return true; } if (perDisplayWakeByTouch()) { diff --git a/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java b/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java index 66a003577e9a..962b5a7010ea 100644 --- a/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java +++ b/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java @@ -52,10 +52,14 @@ public interface WindowWakeUpPolicyInternal { * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}. * @param source the {@link android.view.InputDevice} source that caused the event. * @param isDown {@code true} if the event's action is {@link MotionEvent#ACTION_DOWN}. + * @param deviceGoingToSleep {@code true} if the device is in the middle of going to sleep. + * This will be {@code false} if the device is currently fully awake or is fully + * asleep (i.e. not trying to go to sleep) * @return {@code true} if the delegate handled the wake up. {@code false} if the delegate * decided not to handle the wake up. The policy will execute the wake up in this case. */ - boolean wakeUpFromMotion(long eventTime, int source, boolean isDown); + boolean wakeUpFromMotion( + long eventTime, int source, boolean isDown, boolean deviceGoingToSleep); } /** diff --git a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java index ebc50fd85f24..52d4555248ce 100644 --- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java +++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java @@ -67,6 +67,10 @@ public class PowerManagerFlags { new FlagState(Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN, Flags::wakelockAttributionViaWorkchain); + private final FlagState mDisableFrozenProcessWakelocks = + new FlagState(Flags.FLAG_DISABLE_FROZEN_PROCESS_WAKELOCKS, + Flags::disableFrozenProcessWakelocks); + /** Returns whether early-screen-timeout-detector is enabled on not. */ public boolean isEarlyScreenTimeoutDetectorEnabled() { return mEarlyScreenTimeoutDetectorFlagState.isEnabled(); @@ -121,6 +125,13 @@ public class PowerManagerFlags { } /** + * @return Whether the feature to disable the frozen process wakelocks is enabled + */ + public boolean isDisableFrozenProcessWakelocksEnabled() { + return mDisableFrozenProcessWakelocks.isEnabled(); + } + + /** * dumps all flagstates * @param pw printWriter */ @@ -132,6 +143,7 @@ public class PowerManagerFlags { pw.println(" " + mFrameworkWakelockInfo); pw.println(" " + mMoveWscLoggingToNotifier); pw.println(" " + mWakelockAttributionViaWorkchain); + pw.println(" " + mDisableFrozenProcessWakelocks); } private static class FlagState { diff --git a/services/core/java/com/android/server/power/feature/power_flags.aconfig b/services/core/java/com/android/server/power/feature/power_flags.aconfig index fefe195dc337..ad8ec0354aa6 100644 --- a/services/core/java/com/android/server/power/feature/power_flags.aconfig +++ b/services/core/java/com/android/server/power/feature/power_flags.aconfig @@ -70,3 +70,10 @@ flag { description: "Feature flag to move logging of WakelockStateChanged atoms from BatteryStatsImpl to Notifier." bug: "352602149" } + +flag { + name: "disable_frozen_process_wakelocks" + namespace: "power" + description: "Feature flag to disable/enable wakelocks of a process when it is frozen/unfrozen" + bug: "291115867" +} diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java index 93fd2768d13e..f5daa8036726 100644 --- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java +++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java @@ -23,7 +23,9 @@ import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.content.SharedPreferences; import android.os.Binder; +import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -32,14 +34,21 @@ import android.os.PermissionEnforcer; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; +import android.os.UserHandle; import android.provider.Settings; import android.security.advancedprotection.AdvancedProtectionFeature; +import android.security.advancedprotection.AdvancedProtectionManager; +import android.security.advancedprotection.AdvancedProtectionManager.FeatureId; +import android.security.advancedprotection.AdvancedProtectionManager.SupportDialogType; import android.security.advancedprotection.IAdvancedProtectionCallback; import android.security.advancedprotection.IAdvancedProtectionService; +import android.security.advancedprotection.AdvancedProtectionProtoEnums; import android.util.ArrayMap; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.DumpUtils; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -50,8 +59,11 @@ import com.android.server.security.advancedprotection.features.DisallowCellular2 import com.android.server.security.advancedprotection.features.DisallowInstallUnknownSourcesAdvancedProtectionHook; import com.android.server.security.advancedprotection.features.MemoryTaggingExtensionHook; import com.android.server.security.advancedprotection.features.UsbDataAdvancedProtectionHook; +import com.android.server.security.advancedprotection.features.DisallowWepAdvancedProtectionProvider; +import java.io.File; import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -61,6 +73,15 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub private static final int MODE_CHANGED = 0; private static final int CALLBACK_ADDED = 1; + // Shared preferences keys + private static final String PREFERENCE = "advanced_protection_preference"; + private static final String ENABLED_CHANGE_TIME = "enabled_change_time"; + private static final String LAST_DIALOG_FEATURE_ID = "last_dialog_feature_id"; + private static final String LAST_DIALOG_TYPE = "last_dialog_type"; + private static final String LAST_DIALOG_HOURS_SINCE_ENABLED = "last_dialog_hours_since_enabled"; + private static final String LAST_DIALOG_LEARN_MORE_CLICKED = "last_dialog_learn_more_clicked"; + private static final long MILLIS_PER_HOUR = 60 * 60 * 1000; + private final Context mContext; private final Handler mHandler; private final AdvancedProtectionStore mStore; @@ -72,6 +93,10 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub // For tracking only - not called on state change private final ArrayList<AdvancedProtectionProvider> mProviders = new ArrayList<>(); + // Used to store logging data + private SharedPreferences mSharedPreferences; + private boolean mEmitLogs = true; + private AdvancedProtectionService(@NonNull Context context) { super(PermissionEnforcer.fromContext(context)); mContext = context; @@ -107,7 +132,9 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub } catch (Exception e) { Slog.e(TAG, "Failed to initialize UsbDataAdvancedProtection", e); } - } + } + + mProviders.add(new DisallowWepAdvancedProtectionProvider()); } // Only for tests @@ -126,6 +153,8 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub if (provider != null) { mProviders.add(provider); } + + mEmitLogs = false; } @Override @@ -178,7 +207,7 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub if (enabled != isAdvancedProtectionEnabledInternal()) { mStore.store(enabled); sendModeChanged(enabled); - Slog.i(TAG, "Advanced protection is " + (enabled ? "enabled" : "disabled")); + logAdvancedProtectionEnabled(enabled); } } } finally { @@ -188,11 +217,96 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub @Override @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) + public void logDialogShown(@FeatureId int featureId, @SupportDialogType int type, + boolean learnMoreClicked) { + logDialogShown_enforcePermission(); + + if (!mEmitLogs) { + return; + } + + int hoursSinceEnabled = hoursSinceLastChange(); + FrameworkStatsLog.write(FrameworkStatsLog.ADVANCED_PROTECTION_SUPPORT_DIALOG_DISPLAYED, + /*feature_id*/ featureIdToLogEnum(featureId), + /*dialogue_type*/ dialogueTypeToLogEnum(type), + /*learn_more_clicked*/ learnMoreClicked, + /*hours_since_last_change*/ hoursSinceEnabled); + + getSharedPreferences().edit() + .putInt(LAST_DIALOG_FEATURE_ID, featureId) + .putInt(LAST_DIALOG_TYPE, type) + .putBoolean(LAST_DIALOG_LEARN_MORE_CLICKED, learnMoreClicked) + .putInt(LAST_DIALOG_HOURS_SINCE_ENABLED, hoursSinceEnabled) + .apply(); + } + + private int featureIdToLogEnum(@FeatureId int featureId) { + switch (featureId) { + case AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G: + return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_CELLULAR_2G; + case AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES: + return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES; + case AdvancedProtectionManager.FEATURE_ID_DISALLOW_USB: + return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_USB; + case AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP: + return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_WEP; + case AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE: + return AdvancedProtectionProtoEnums.FEATURE_ID_ENABLE_MTE; + default: + return AdvancedProtectionProtoEnums.FEATURE_ID_UNKNOWN; + } + } + + private int dialogueTypeToLogEnum(@SupportDialogType int type) { + switch (type) { + case AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN: + return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_UNKNOWN; + case AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION: + return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_BLOCKED_INTERACTION; + case AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING: + return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_DISABLED_SETTING; + default: + return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_UNKNOWN; + } + } + + private void logAdvancedProtectionEnabled(boolean enabled) { + if (!mEmitLogs) { + return; + } + + Slog.i(TAG, "Advanced protection has been " + (enabled ? "enabled" : "disabled")); + SharedPreferences prefs = getSharedPreferences(); + FrameworkStatsLog.write(FrameworkStatsLog.ADVANCED_PROTECTION_STATE_CHANGED, + /*enabled*/ enabled, + /*hours_since_enabled*/ hoursSinceLastChange(), + /*last_dialog_feature_id*/ featureIdToLogEnum( + prefs.getInt(LAST_DIALOG_FEATURE_ID, -1)), + /*_type*/ dialogueTypeToLogEnum(prefs.getInt(LAST_DIALOG_TYPE, -1)), + /*_learn_more_clicked*/ prefs.getBoolean(LAST_DIALOG_LEARN_MORE_CLICKED, false), + /*_hours_since_enabled*/ prefs.getInt(LAST_DIALOG_HOURS_SINCE_ENABLED, -1)); + prefs.edit() + .putLong(ENABLED_CHANGE_TIME, System.currentTimeMillis()) + .apply(); + } + + private int hoursSinceLastChange() { + int hoursSinceEnabled = -1; + long lastChangeTimeMillis = getSharedPreferences().getLong(ENABLED_CHANGE_TIME, -1); + if (lastChangeTimeMillis != -1) { + hoursSinceEnabled = (int) + ((System.currentTimeMillis() - lastChangeTimeMillis) / MILLIS_PER_HOUR); + } + return hoursSinceEnabled; + } + + @Override + @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() { getAdvancedProtectionFeatures_enforcePermission(); List<AdvancedProtectionFeature> features = new ArrayList<>(); for (int i = 0; i < mProviders.size(); i++) { - features.addAll(mProviders.get(i).getFeatures()); + features.addAll(mProviders.get(i).getFeatures(mContext)); } for (int i = 0; i < mHooks.size(); i++) { @@ -213,6 +327,30 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub .exec(this, in, out, err, args, callback, resultReceiver); } + @Override + public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return; + writer.println("AdvancedProtectionService"); + writer.println(" isAdvancedProtectionEnabled: " + isAdvancedProtectionEnabledInternal()); + writer.println(" mHooks.size(): " + mHooks.size()); + writer.println(" mCallbacks.size(): " + mCallbacks.size()); + writer.println(" mProviders.size(): " + mProviders.size()); + + writer.println("Hooks: "); + mHooks.stream().forEach(hook -> { + writer.println(" " + hook.getClass().getSimpleName() + + " available: " + hook.isAvailable()); + }); + writer.println(" Providers: "); + mProviders.stream().forEach(provider -> { + writer.println(" " + provider.getClass().getSimpleName()); + provider.getFeatures(mContext).stream().forEach(feature -> { + writer.println(" " + feature.getClass().getSimpleName()); + }); + }); + writer.println(" mSharedPreferences: " + getSharedPreferences().getAll()); + } + void sendModeChanged(boolean enabled) { Message.obtain(mHandler, MODE_CHANGED, /*enabled*/ enabled ? 1 : 0, /*unused */ -1) .sendToTarget(); @@ -224,6 +362,22 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub .sendToTarget(); } + private SharedPreferences getSharedPreferences() { + if (mSharedPreferences == null) { + initSharedPreferences(); + } + return mSharedPreferences; + } + + private synchronized void initSharedPreferences() { + if (mSharedPreferences == null) { + Context deviceContext = mContext.createDeviceProtectedStorageContext(); + File sharedPrefs = new File(Environment.getDataSystemDirectory(), PREFERENCE); + mSharedPreferences = deviceContext.getSharedPreferences(sharedPrefs, + Context.MODE_PRIVATE); + } + } + public static final class Lifecycle extends SystemService { private final AdvancedProtectionService mService; diff --git a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java index ed451f1e2257..6498cfc97aac 100644 --- a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java +++ b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java @@ -16,6 +16,8 @@ package com.android.server.security.advancedprotection.features; +import android.annotation.NonNull; +import android.content.Context; import android.security.advancedprotection.AdvancedProtectionFeature; import java.util.List; @@ -23,5 +25,5 @@ import java.util.List; /** @hide */ public abstract class AdvancedProtectionProvider { /** The list of features provided */ - public abstract List<AdvancedProtectionFeature> getFeatures(); + public abstract List<AdvancedProtectionFeature> getFeatures(@NonNull Context context); } diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java index be263346854e..bf464be4a170 100644 --- a/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java +++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java @@ -22,16 +22,11 @@ import static android.security.advancedprotection.AdvancedProtectionManager.FEAT import android.annotation.NonNull; import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.content.pm.PackageManager; import android.os.UserManager; import android.security.advancedprotection.AdvancedProtectionFeature; -import android.telephony.SubscriptionInfo; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; import android.util.Slog; -import java.util.ArrayList; -import java.util.List; - /** @hide */ public final class DisallowCellular2GAdvancedProtectionHook extends AdvancedProtectionHook { private static final String TAG = "AdvancedProtectionDisallowCellular2G"; @@ -39,14 +34,12 @@ public final class DisallowCellular2GAdvancedProtectionHook extends AdvancedProt private final AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature(FEATURE_ID_DISALLOW_CELLULAR_2G); private final DevicePolicyManager mDevicePolicyManager; - private final TelephonyManager mTelephonyManager; - private final SubscriptionManager mSubscriptionManager; + private final PackageManager mPackageManager; public DisallowCellular2GAdvancedProtectionHook(@NonNull Context context, boolean enabled) { super(context, enabled); mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); - mTelephonyManager = context.getSystemService(TelephonyManager.class); - mSubscriptionManager = context.getSystemService(SubscriptionManager.class); + mPackageManager = context.getPackageManager(); onAdvancedProtectionChanged(enabled); } @@ -57,40 +50,9 @@ public final class DisallowCellular2GAdvancedProtectionHook extends AdvancedProt return mFeature; } - private static boolean isEmbeddedSubscriptionVisible(SubscriptionInfo subInfo) { - if (subInfo.isEmbedded() - && (subInfo.getProfileClass() == SubscriptionManager.PROFILE_CLASS_PROVISIONING - || subInfo.isOnlyNonTerrestrialNetwork())) { - return false; - } - - return true; - } - - private List<TelephonyManager> getActiveTelephonyManagers() { - List<TelephonyManager> telephonyManagers = new ArrayList<>(); - - for (SubscriptionInfo subInfo : mSubscriptionManager.getActiveSubscriptionInfoList()) { - if (isEmbeddedSubscriptionVisible(subInfo)) { - telephonyManagers.add( - mTelephonyManager.createForSubscriptionId(subInfo.getSubscriptionId())); - } - } - - return telephonyManagers; - } - @Override public boolean isAvailable() { - for (TelephonyManager telephonyManager : getActiveTelephonyManagers()) { - if (telephonyManager.isDataCapable() - && telephonyManager.isRadioInterfaceCapabilitySupported( - mTelephonyManager.CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK)) { - return true; - } - } - - return false; + return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); } @Override diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowWepAdvancedProtectionProvider.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowWepAdvancedProtectionProvider.java new file mode 100644 index 000000000000..1505f68b699e --- /dev/null +++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowWepAdvancedProtectionProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.security.advancedprotection.features; + +import android.annotation.NonNull; +import android.content.Context; +import android.net.wifi.WifiManager; +import android.security.advancedprotection.AdvancedProtectionFeature; + +import java.util.List; + +public class DisallowWepAdvancedProtectionProvider extends AdvancedProtectionProvider { + public List<AdvancedProtectionFeature> getFeatures(@NonNull Context context) { + WifiManager wifiManager = context.getSystemService(WifiManager.class); + return wifiManager.getAvailableAdvancedProtectionFeatures(); + } +} diff --git a/services/core/java/com/android/server/sensors/OWNERS b/services/core/java/com/android/server/sensors/OWNERS new file mode 100644 index 000000000000..6b2247331a33 --- /dev/null +++ b/services/core/java/com/android/server/sensors/OWNERS @@ -0,0 +1 @@ +include platform/frameworks/native:/services/sensorservice/OWNERS diff --git a/services/core/java/com/android/server/sensors/SensorManagerInternal.java b/services/core/java/com/android/server/sensors/SensorManagerInternal.java index 7ff4ade1101c..9636cc6c77a7 100644 --- a/services/core/java/com/android/server/sensors/SensorManagerInternal.java +++ b/services/core/java/com/android/server/sensors/SensorManagerInternal.java @@ -17,6 +17,7 @@ package com.android.server.sensors; import android.annotation.NonNull; +import android.annotation.Nullable; import android.hardware.SensorDirectChannel; import android.os.ParcelFileDescriptor; @@ -71,7 +72,7 @@ public abstract class SensorManagerInternal { /** * Sends an event for the runtime sensor with the given handle to the framework. * - * Only relevant for sending runtime sensor events. @see #createRuntimeSensor. + * <p>Only relevant for sending runtime sensor events. @see #createRuntimeSensor.</p> * * @param handle The sensor handle. * @param type The type of the sensor. @@ -83,6 +84,21 @@ public abstract class SensorManagerInternal { @NonNull float[] values); /** + * Sends an additional info event for the runtime sensor with the given handle to the framework. + * + * <p>Only relevant for runtime sensors. @see #createRuntimeSensor.</p> + * + * @param handle The sensor handle. + * @param type The type of payload data. + * @param serial The sequence number of this frame for this type. + * @param timestampNanos Timestamp of the event. + * @param values The payload data represented in float values. + * @return Whether the event injection was successful. + */ + public abstract boolean sendSensorAdditionalInfo(int handle, int type, int serial, + long timestampNanos, @Nullable float[] values); + + /** * Listener for proximity sensor state changes. */ public interface ProximityActiveListener { diff --git a/services/core/java/com/android/server/sensors/SensorService.java b/services/core/java/com/android/server/sensors/SensorService.java index 3de191030d71..0d31b22e2020 100644 --- a/services/core/java/com/android/server/sensors/SensorService.java +++ b/services/core/java/com/android/server/sensors/SensorService.java @@ -19,6 +19,7 @@ package com.android.server.sensors; import static com.android.server.sensors.SensorManagerInternal.ProximityActiveListener; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.util.ArrayMap; @@ -62,6 +63,9 @@ public class SensorService extends SystemService { private static native void unregisterRuntimeSensorNative(long ptr, int handle); private static native boolean sendRuntimeSensorEventNative(long ptr, int handle, int type, long timestampNanos, float[] values); + private static native boolean sendRuntimeSensorAdditionalInfoNative(long ptr, int handle, + int type, int serial, long timestampNanos, float[] values); + public SensorService(Context ctx) { super(ctx); @@ -129,6 +133,18 @@ public class SensorService extends SystemService { } @Override + public boolean sendSensorAdditionalInfo(int handle, int type, int serial, + long timestampNanos, @Nullable float[] values) { + synchronized (mLock) { + if (!mRuntimeSensorHandles.contains(handle)) { + return false; + } + return sendRuntimeSensorAdditionalInfoNative(mPtr, handle, type, serial, + timestampNanos, values); + } + } + + @Override public void addProximityActiveListener(@NonNull Executor executor, @NonNull ProximityActiveListener listener) { Objects.requireNonNull(executor, "executor must not be null"); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index df00fa195f03..b76b23161e78 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5583,6 +5583,13 @@ final class ActivityRecord extends WindowToken { // called for updating snapshot states. if (!fromTransition) { mWmService.mSnapshotController.notifyAppVisibilityChanged(this, visible); + if (visible) { + // In case the activity becomes visible without transition, the client still expects + // to receive Activity#onEnterAnimationComplete. + mEnteringAnimation = true; + mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked( + token); + } } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index b7ef1057388c..0e14f83c96f8 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2650,9 +2650,13 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ void endDeferResume() { mDeferResumeCount--; - if (readyToResume() && mLastReportedTopResumedActivity != null - && mTopResumedActivity != mLastReportedTopResumedActivity) { - scheduleTopResumedActivityStateLossIfNeeded(); + if (readyToResume()) { + if (mLastReportedTopResumedActivity != null + && mTopResumedActivity != mLastReportedTopResumedActivity) { + scheduleTopResumedActivityStateLossIfNeeded(); + } else if (mLastReportedTopResumedActivity == null) { + scheduleTopResumedActivityStateIfNeeded(); + } } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 59a042981375..2f9242fbdfc9 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -7085,12 +7085,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } @Override - public void setAnimatingTypes(@InsetsType int animatingTypes) { + public void setAnimatingTypes(@InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { if (mAnimatingTypes != animatingTypes) { mAnimatingTypes = animatingTypes; if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) { - getInsetsStateController().onAnimatingTypesChanged(this); + getInsetsStateController().onAnimatingTypesChanged(this, statsToken); } } } diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index 7b6fc9e5694d..64ae21dc69de 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -239,9 +239,10 @@ class EmbeddedWindowController { static class EmbeddedWindow implements InputTarget { final IBinder mClient; - @Nullable final WindowState mHostWindowState; + @Nullable WindowState mHostWindowState; @Nullable final ActivityRecord mHostActivityRecord; - final String mName; + String mName; + final String mInputHandleName; final int mOwnerUid; final int mOwnerPid; final WindowManagerService mWmService; @@ -279,13 +280,12 @@ class EmbeddedWindowController { * @param displayId used for focus requests */ EmbeddedWindow(Session session, WindowManagerService service, IBinder clientToken, - WindowState hostWindowState, int ownerUid, int ownerPid, int windowType, - int displayId, InputTransferToken inputTransferToken, String inputHandleName, - boolean isFocusable) { + @Nullable WindowState hostWindowState, int ownerUid, int ownerPid, + int windowType, int displayId, InputTransferToken inputTransferToken, + String inputHandleName, boolean isFocusable) { mSession = session; mWmService = service; mClient = clientToken; - mHostWindowState = hostWindowState; mHostActivityRecord = (mHostWindowState != null) ? mHostWindowState.mActivityRecord : null; mOwnerUid = ownerUid; @@ -293,11 +293,9 @@ class EmbeddedWindowController { mWindowType = windowType; mDisplayId = displayId; mInputTransferToken = inputTransferToken; - final String hostWindowName = - (mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString() - : ""; mIsFocusable = isFocusable; - mName = "Embedded{" + inputHandleName + hostWindowName + "}"; + mInputHandleName = inputHandleName; + updateHost(hostWindowState); } @Override @@ -486,5 +484,19 @@ class EmbeddedWindowController { proto.end(token2); proto.end(token); } + + public void updateHost(WindowState hostWindowState) { + if (mHostWindowState == hostWindowState && mName != null) { + return; + } + + ProtoLog.d(WM_DEBUG_EMBEDDED_WINDOWS, "[%s] Updated host window from %s to %s", + this, mHostWindowState, hostWindowState); + mHostWindowState = hostWindowState; + final String hostWindowName = + (mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString() + : ""; + mName = "Embedded{" + mInputHandleName + hostWindowName + "}"; + } } } diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index 040bbe46c3aa..53681f950c8e 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -82,6 +82,13 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { */ private boolean mGivenInsetsReady = false; + /** + * The last state of the windowContainer. This is used to reset server visibility, in case of + * the IME (temporarily) redrawing (e.g. during a rotation), to dispatch the control with + * leash again after it has finished drawing. + */ + private boolean mLastDrawn = false; + ImeInsetsSourceProvider(@NonNull InsetsSource source, @NonNull InsetsStateController stateController, @NonNull DisplayContent displayContent) { @@ -97,6 +104,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { final WindowState ws = mWindowContainer != null ? mWindowContainer.asWindowState() : null; final boolean givenInsetsPending = ws != null && ws.mGivenInsetsPending; + mLastDrawn = ws != null && ws.isDrawn(); // isLeashReadyForDispatching (used to dispatch the leash of the control) is // depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here @@ -158,6 +166,35 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { } } + /** + * This is used to determine the desired serverVisibility state. For the IME, just having a + * window state that would be visible by policy is not enough. + */ + @Override + protected boolean isSurfaceVisible() { + final boolean isSurfaceVisible = super.isSurfaceVisible(); + if (android.view.inputmethod.Flags.refactorInsetsController()) { + final WindowState windowState = mWindowContainer.asWindowState(); + if (mControl != null && windowState != null) { + final boolean isDrawn = windowState.isDrawn(); + if (!isServerVisible() && isSurfaceVisible) { + // In case the IME becomes visible, we need to check if it is already drawn and + // does not have given insets pending. If it's not yet drawn, we do not set + // server visibility + return isDrawn && !windowState.mGivenInsetsPending; + } else if (mLastDrawn && !isDrawn) { + // If the IME was drawn before, but is not drawn anymore, we need to reset + // server visibility, which will also reset {@link + // ImeInsetsSourceProvider#mGivenInsetsReady}. Otherwise, the new control + // with leash won't be dispatched after the surface has redrawn. + return false; + } + } + } + return isSurfaceVisible; + } + + @Nullable @Override InsetsSourceControl getControl(InsetsControlTarget target) { @@ -284,7 +321,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { if (Flags.refactorInsetsController()) { // TODO(b/353463205) investigate if we should fail the statsToken, or if it's only // temporary null. - if (target != null) { + if (target != null && target == mControlTarget) { // If insets target is not available (e.g. RemoteInsetsControlTarget), use current // IME input target to update IME request state. For example, switch from a task // with showing IME to a split-screen task without showing IME. @@ -297,6 +334,11 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { } else { invokeOnImeRequestedChangedListener(target, statsToken); } + } else { + ProtoLog.w(WM_DEBUG_IME, + "Not invoking onImeRequestedChangedListener, target=%s, current " + + "controlTarget=%s", + target, mControlTarget); } } } @@ -424,7 +466,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { } @Override - void onAnimatingTypesChanged(InsetsControlTarget caller) { + void onAnimatingTypesChanged(InsetsControlTarget caller, + @Nullable ImeTracker.Token statsToken) { if (Flags.reportAnimatingInsetsTypes()) { final InsetsControlTarget controlTarget = getControlTarget(); // If the IME is not being requested anymore and the animation is finished, we need to @@ -432,8 +475,12 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { if (caller != null && caller == controlTarget && !caller.isRequestedVisible( WindowInsets.Type.ime()) && (caller.getAnimatingTypes() & WindowInsets.Type.ime()) == 0) { - // TODO(b/353463205) check statsToken - invokeOnImeRequestedChangedListener(caller, null); + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED); + invokeOnImeRequestedChangedListener(caller, statsToken); + } else { + ImeTracker.forLogging().onCancelled(statsToken, + ImeTracker.PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED); } } } @@ -779,6 +826,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { pw.print(prefix); pw.print("mImeShowing="); pw.print(mImeShowing); + pw.print(" mLastDrawn="); + pw.print(mLastDrawn); if (mImeRequester != null) { pw.print(prefix); pw.print("showImePostLayout pending for mImeRequester="); diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java index 6462a37ae33f..3c248fbc7daa 100644 --- a/services/core/java/com/android/server/wm/InsetsControlTarget.java +++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java @@ -107,8 +107,10 @@ interface InsetsControlTarget extends InsetsTarget { /** * @param animatingTypes the {@link InsetsType}s, that are currently animating + * @param statsToken the token tracking the current IME request or {@code null} otherwise. */ - default void setAnimatingTypes(@InsetsType int animatingTypes) { + default void setAnimatingTypes(@InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { } /** Returns {@code target.getWindow()}, or null if {@code target} is {@code null}. */ diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 1b693fc05b21..3b715d652dca 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -176,6 +176,16 @@ class InsetsSourceProvider { } /** + * @return Whether the current window container has a visible surface. + */ + protected boolean isSurfaceVisible() { + final WindowState windowState = mWindowContainer.asWindowState(); + return windowState != null + ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy() + : mWindowContainer.isVisibleRequested(); + } + + /** * Updates the window container that currently backs this source. * * @param windowContainer The window container that links to this source. @@ -368,20 +378,9 @@ class InsetsSourceProvider { if (mWindowContainer == null) { return; } - WindowState windowState = mWindowContainer.asWindowState(); - boolean isServerVisible = windowState != null - ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy() - : mWindowContainer.isVisibleRequested(); + final WindowState windowState = mWindowContainer.asWindowState(); + final boolean isServerVisible = isSurfaceVisible(); - if (android.view.inputmethod.Flags.refactorInsetsController()) { - if (mControl != null && mControl.getType() == WindowInsets.Type.ime() && !mServerVisible - && isServerVisible && windowState != null) { - // in case the IME becomes visible, we need to check if it is already drawn and - // does not have given insets pending. If it's not yet drawn, we do not set - // server visibility - isServerVisible = windowState.isDrawn() && !windowState.mGivenInsetsPending; - } - } final boolean serverVisibleChanged = mServerVisible != isServerVisible; setServerVisible(isServerVisible); if (mControl != null && mControlTarget != null) { @@ -673,7 +672,8 @@ class InsetsSourceProvider { mServerVisible, mClientVisible); } - void onAnimatingTypesChanged(InsetsControlTarget caller) { + void onAnimatingTypesChanged(InsetsControlTarget caller, + @Nullable ImeTracker.Token statsToken) { } protected boolean isLeashReadyForDispatching() { diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 810e48f492e1..64fe6699a262 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -393,10 +393,12 @@ class InsetsStateController { } } - void onAnimatingTypesChanged(InsetsControlTarget target) { + void onAnimatingTypesChanged(InsetsControlTarget target, + @Nullable ImeTracker.Token statsToken) { for (int i = mProviders.size() - 1; i >= 0; i--) { final InsetsSourceProvider provider = mProviders.valueAt(i); - provider.onAnimatingTypesChanged(target); + final boolean isImeProvider = provider.getSource().getType() == WindowInsets.Type.ime(); + provider.onAnimatingTypesChanged(target, isImeProvider ? statsToken : null); } } diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java index 4f8ec631d9e2..be259ec3f7c0 100644 --- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java +++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java @@ -80,7 +80,7 @@ public class PointerEventDispatcher extends InputEventReceiver { public void unregisterInputEventListener(PointerEventListener listener) { synchronized (mListeners) { if (!mListeners.contains(listener)) { - throw new IllegalStateException("registerInputEventListener: " + listener + + throw new IllegalStateException("unregisterInputEventListener: " + listener + " not registered."); } mListeners.remove(listener); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 242aea941429..39d10624469c 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -853,7 +853,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Post these on a handler such that we don't call into power manager service while // holding the window manager lock to avoid lock contention with power manager lock. - mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, mDisplayBrightnessOverrides) + // Send a copy of the brightness overrides as they may be cleared before being sent out. + mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, mDisplayBrightnessOverrides.clone()) .sendToTarget(); mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget(); diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 3ed16db7e204..c5b47f9f4256 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -738,12 +738,18 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes) { + public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { synchronized (mService.mGlobalLock) { final WindowState win = mService.windowForClientLocked(this, window, false /* throwOnError */); if (win != null) { - win.setAnimatingTypes(animatingTypes); + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_UPDATE_ANIMATING_TYPES); + win.setAnimatingTypes(animatingTypes, statsToken); + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_UPDATE_ANIMATING_TYPES); } } } @@ -910,10 +916,16 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { int privateFlags, int inputFeatures, int type, IBinder windowToken, InputTransferToken inputTransferToken, String inputHandleName, InputChannel outInputChannel) { - if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) { - // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to - // embedded windows without providing a host window input token - throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); + if (!Flags.updateHostInputTransferToken()) { + // This is not a valid security check, callers can pass in a bogus token. If the + // token is not known to wm, then input APIs is request focus or transferTouchGesture + // will fail. Removing this check allows SCVH to be created before associating with a + // host window. + if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) { + // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to + // embedded windows without providing a host window input token + throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); + } } final long identity = Binder.clearCallingIdentity(); @@ -928,12 +940,14 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, + public void updateInputChannel(IBinder channelToken, + @Nullable InputTransferToken hostInputTransferToken, + int displayId, SurfaceControl surface, int flags, int privateFlags, int inputFeatures, Region region) { final long identity = Binder.clearCallingIdentity(); try { - mService.updateInputChannel(channelToken, displayId, surface, flags, - mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region); + mService.updateInputChannel(channelToken, hostInputTransferToken, displayId, surface, + flags, mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 30313fc63857..2c10af4c5851 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -3191,7 +3191,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { // Fixed rotation only applies to opening or changing activity. return; } - if (task.inMultiWindowMode() && taskTopRunning.inMultiWindowMode()) { + if (!ActivityTaskManagerService.isPip2ExperimentEnabled() + && task.inMultiWindowMode() && taskTopRunning.inMultiWindowMode()) { // Display won't be rotated for multi window Task, so the fixed rotation won't be // applied. This can happen when the windowing mode is changed before the previous // fixed rotation is applied. Check both task and activity because the activity keeps diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index e1553cd37d03..b042e111e331 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -117,8 +117,11 @@ class WallpaperController { private boolean mShouldOffsetWallpaperCenter; // This is for WallpaperCropper, which has cropping logic for the default display only. + // This is lazily initialization by getOrCreateDefaultDisplayInfo. DO NOT use this member + // variable directly. // TODO(b/400685784) make the WallpaperCropper operate on every display independently - private final WallpaperDefaultDisplayInfo mDefaultDisplayInfo; + @Nullable + private WallpaperDefaultDisplayInfo mDefaultDisplayInfo = null; private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> { final ActivityRecord ar = w.mActivityRecord; @@ -202,14 +205,12 @@ class WallpaperController { WallpaperController(WindowManagerService service, DisplayContent displayContent) { mService = service; mDisplayContent = displayContent; - WindowManager windowManager = service.mContext.getSystemService(WindowManager.class); Resources resources = service.mContext.getResources(); mMinWallpaperScale = resources.getFloat(com.android.internal.R.dimen.config_wallpaperMinScale); mMaxWallpaperScale = resources.getFloat(R.dimen.config_wallpaperMaxScale); mShouldOffsetWallpaperCenter = resources.getBoolean( com.android.internal.R.bool.config_offsetWallpaperToCenterOfLargestDisplay); - mDefaultDisplayInfo = new WallpaperDefaultDisplayInfo(windowManager, resources); } void resetLargestDisplay(Display display) { @@ -358,8 +359,8 @@ class WallpaperController { wallpaperWin.mRequestedWidth, wallpaperWin.mRequestedHeight); SparseArray<Rect> cropHints = token.getCropHints(); wallpaperFrame = bitmapSize.x <= 0 || bitmapSize.y <= 0 ? wallpaperWin.getFrame() - : WallpaperCropper.getCrop(screenSize, mDefaultDisplayInfo, bitmapSize, - cropHints, wallpaperWin.isRtl()); + : WallpaperCropper.getCrop(screenSize, getOrCreateDefaultDisplayInfo(), + bitmapSize, cropHints, wallpaperWin.isRtl()); int frameWidth = wallpaperFrame.width(); int frameHeight = wallpaperFrame.height(); float frameRatio = (float) frameWidth / frameHeight; @@ -506,6 +507,16 @@ class WallpaperController { return changed; } + private WallpaperDefaultDisplayInfo getOrCreateDefaultDisplayInfo() { + if (mDefaultDisplayInfo != null) { + return mDefaultDisplayInfo; + } + WindowManager windowManager = mService.mContext.getSystemService(WindowManager.class); + Resources resources = mService.mContext.getResources(); + mDefaultDisplayInfo = new WallpaperDefaultDisplayInfo(windowManager, resources); + return mDefaultDisplayInfo; + } + /** * Get an extra offset if needed ({@link #mShouldOffsetWallpaperCenter} = true, typically on * multiple display devices) so that the wallpaper in a smaller display ends up centered at the diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ff43d72c5a07..fb38c581d222 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4754,7 +4754,8 @@ public class WindowManagerService extends IWindowManager.Stub @EnforcePermission(android.Manifest.permission.MANAGE_APP_TOKENS) @Override - public void updateDisplayWindowAnimatingTypes(int displayId, @InsetsType int animatingTypes) { + public void updateDisplayWindowAnimatingTypes(int displayId, @InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { updateDisplayWindowAnimatingTypes_enforcePermission(); if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) { final long origId = Binder.clearCallingIdentity(); @@ -4762,9 +4763,13 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc == null || dc.mRemoteInsetsControlTarget == null) { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES); return; } - dc.mRemoteInsetsControlTarget.setAnimatingTypes(animatingTypes); + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES); + dc.mRemoteInsetsControlTarget.setAnimatingTypes(animatingTypes, statsToken); } } finally { Binder.restoreCallingIdentity(origId); @@ -7614,6 +7619,26 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public boolean isEligibleForDesktopMode(int displayId) { + if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "isEligibleForDesktopMode()")) { + throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); + } + + synchronized (mGlobalLock) { + final DisplayContent displayContent = mRoot.getDisplayContent(displayId); + if (displayContent == null) { + ProtoLog.e(WM_ERROR, "Attempted to check isEligibleForDesktopMode() " + + "for a display that does not exist: %d", displayId); + return false; + } + if (!displayContent.isSystemDecorationsSupported()) { + return false; + } + return displayContent.isDefaultDisplay || displayContent.allowContentModeSwitch(); + } + } + + @Override public void setShouldShowSystemDecors(int displayId, boolean shouldShow) { if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) { throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); @@ -9353,10 +9378,12 @@ public class WindowManagerService extends IWindowManager.Stub /** * Updates the flags on an existing surface's input channel. This assumes the surface provided - * is the one associated with the provided input-channel. If this isn't the case, behavior - * is undefined. + * is the one associated with the provided input-channel. If this isn't the case, behavior is + * undefined. */ - void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, + void updateInputChannel(IBinder channelToken, + @Nullable InputTransferToken hostInputTransferToken, int displayId, + SurfaceControl surface, int flags, int privateFlags, int inputFeatures, Region region) { final InputApplicationHandle applicationHandle; final String name; @@ -9370,6 +9397,11 @@ public class WindowManagerService extends IWindowManager.Stub name = win.toString(); applicationHandle = win.getApplicationHandle(); win.setIsFocusable((flags & FLAG_NOT_FOCUSABLE) == 0); + if (Flags.updateHostInputTransferToken()) { + WindowState hostWindowState = hostInputTransferToken != null + ? mInputToWindowMap.get(hostInputTransferToken.getToken()) : null; + win.updateHost(hostWindowState); + } } updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name, diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index bdd13722aba4..d356128205df 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -337,6 +337,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio public static final int ACTIVITY_STATE_FLAG_VISIBLE_MULTI_WINDOW_MODE = 1 << 25; public static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff; + private static final int ACTIVITY_STATE_VISIBLE = + com.android.window.flags.Flags.useVisibleRequestedForProcessTracker() + ? ACTIVITY_STATE_FLAG_IS_VISIBLE + : ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE; + /** * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the * lower 16 bits are the task layer rank (see {@link Task#mLayerRank}). This field is written by @@ -1260,8 +1265,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio int nonOccludedRatio = 0; long perceptibleTaskStoppedTimeMillis = Long.MIN_VALUE; final boolean wasResumed = hasResumedActivity(); - final boolean wasAnyVisible = (mActivityStateFlags - & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0; + final boolean wasAnyVisible = (mActivityStateFlags & ACTIVITY_STATE_VISIBLE) != 0; for (int i = mActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = mActivities.get(i); if (r.isVisible()) { @@ -1275,8 +1279,9 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio if (task.mLayerRank != Task.LAYER_RANK_INVISIBLE) { stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK; } + final ActivityRecord.State state = r.getState(); if (r.isVisibleRequested()) { - if (r.isState(RESUMED)) { + if (state == RESUMED) { stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED; final int windowingMode = r.getWindowingMode(); if (windowingMode == WINDOWING_MODE_MULTI_WINDOW @@ -1301,13 +1306,21 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // this process, we'd find out the one with the minimal layer, thus it'll // get a higher adj score. } else if (!visible && bestInvisibleState != PAUSING) { - if (r.isState(PAUSING, PAUSED)) { + if (state == PAUSING) { bestInvisibleState = PAUSING; - } else if (r.isState(STOPPING)) { + // Treat PAUSING as visible in case the next activity in the same process has + // not yet been set as visible-requested. + if (com.android.window.flags.Flags.useVisibleRequestedForProcessTracker() + && r.isVisible()) { + stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE; + } + } else if (state == PAUSED) { + bestInvisibleState = PAUSED; + } else if (state == STOPPING) { bestInvisibleState = STOPPING; // Not "finishing" if any of activity isn't finishing. allStoppingFinishing &= r.finishing; - } else if (bestInvisibleState == DESTROYED && r.isState(STOPPED)) { + } else if (bestInvisibleState == DESTROYED && state == STOPPED) { if (task.mIsPerceptible) { perceptibleTaskStoppedTimeMillis = Long.max(r.mStoppedTime, perceptibleTaskStoppedTimeMillis); @@ -1340,7 +1353,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio stateFlags |= minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; if (visible) { stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE; - } else if (bestInvisibleState == PAUSING) { + } else if (bestInvisibleState == PAUSING || bestInvisibleState == PAUSED) { stateFlags |= ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED; } else if (bestInvisibleState == STOPPING) { stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING; @@ -1351,8 +1364,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio mActivityStateFlags = stateFlags; mPerceptibleTaskStoppedTimeMillis = perceptibleTaskStoppedTimeMillis; - final boolean anyVisible = (stateFlags - & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0; + final boolean anyVisible = (stateFlags & ACTIVITY_STATE_VISIBLE) != 0; if (!wasAnyVisible && anyVisible) { mAtm.mVisibleActivityProcessTracker.onAnyActivityVisible(this); mAtm.mWindowManager.onProcessActivityVisibilityChanged(mUid, true /*visible*/); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index a270af56cbcd..af5200102fc0 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -821,7 +821,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } @Override - public void setAnimatingTypes(@InsetsType int animatingTypes) { + public void setAnimatingTypes(@InsetsType int animatingTypes, + @Nullable ImeTracker.Token statsToken) { if (mAnimatingTypes != animatingTypes) { if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) { Trace.instant(TRACE_TAG_WINDOW_MANAGER, @@ -835,10 +836,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mAnimatingTypes = animatingTypes; if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED); final InsetsStateController insetsStateController = getDisplayContent().getInsetsStateController(); - insetsStateController.onAnimatingTypesChanged(this); + insetsStateController.onAnimatingTypesChanged(this, statsToken); } + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED); } } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 66d04df8095b..adfabe1e54fd 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -169,7 +169,7 @@ cc_defaults { "android.hardware.broadcastradio@1.1", "android.hardware.contexthub@1.0", "android.hardware.common.fmq-V1-ndk", - "android.hardware.gnss-V3-cpp", + "android.hardware.gnss-V5-cpp", "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", @@ -204,6 +204,7 @@ cc_defaults { "android.system.suspend.control-V1-cpp", "android.system.suspend.control.internal-cpp", "android.system.suspend-V1-ndk", + "android_location_flags_c_lib", "server_configurable_flags", "service.incremental", ], diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 9c033e25c04e..93f6e95b6d5c 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -36,6 +36,7 @@ #include <android/hardware/gnss/BnGnssMeasurementCallback.h> #include <android/hardware/gnss/BnGnssPowerIndicationCallback.h> #include <android/hardware/gnss/BnGnssPsdsCallback.h> +#include <android_location_flags.h> #include <binder/IServiceManager.h> #include <nativehelper/JNIHelp.h> #include <pthread.h> @@ -53,6 +54,8 @@ #include "gnss/Gnss.h" #include "gnss/GnssAntennaInfo.h" #include "gnss/GnssAntennaInfoCallback.h" +#include "gnss/GnssAssistance.h" +#include "gnss/GnssAssistanceCallback.h" #include "gnss/GnssBatching.h" #include "gnss/GnssConfiguration.h" #include "gnss/GnssDebug.h" @@ -114,6 +117,7 @@ using android::hardware::gnss::GnssConstellationType; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPowerIndicationCallback; +using android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback; using IGnssAidl = android::hardware::gnss::IGnss; using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching; @@ -140,6 +144,9 @@ std::unique_ptr<android::gnss::GnssPsdsInterface> gnssPsdsIface = nullptr; std::unique_ptr<android::gnss::GnssVisibilityControlInterface> gnssVisibilityControlIface = nullptr; std::unique_ptr<android::gnss::MeasurementCorrectionsInterface> gnssMeasurementCorrectionsIface = nullptr; +std::unique_ptr<android::gnss::GnssAssistanceInterface> gnssAssistanceIface = nullptr; + +namespace location_flags = android::location::flags; namespace android { @@ -229,6 +236,9 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc gnss::GnssVisibilityControl_class_init_once(env, clazz); gnss::MeasurementCorrections_class_init_once(env, clazz); gnss::MeasurementCorrectionsCallback_class_init_once(env, clazz); + if (location_flags::gnss_assistance_interface_jni()) { + gnss::GnssAssistance_class_init_once(env, clazz); + } gnss::Utils_class_init_once(env); } @@ -266,7 +276,9 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject gnssBatchingIface = gnssHal->getGnssBatchingInterface(); gnssVisibilityControlIface = gnssHal->getGnssVisibilityControlInterface(); gnssPowerIndicationIface = gnssHal->getGnssPowerIndicationInterface(); - + if (location_flags::gnss_assistance_interface_jni()) { + gnssAssistanceIface = gnssHal->getGnssAssistanceInterface(); + } if (mCallbacksObj) { ALOGE("Callbacks already initialized"); } else { @@ -355,13 +367,22 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl // Set IGnssPowerIndication.hal callback. if (gnssPowerIndicationIface != nullptr) { sp<IGnssPowerIndicationCallback> gnssPowerIndicationCallback = - new GnssPowerIndicationCallback(); + sp<GnssPowerIndicationCallback>::make(); auto status = gnssPowerIndicationIface->setCallback(gnssPowerIndicationCallback); if (!checkAidlStatus(status, "IGnssPowerIndication setCallback() failed.")) { gnssPowerIndicationIface = nullptr; } } + // Set IGnssAssistance callback. + if (gnssAssistanceIface != nullptr) { + sp<IGnssAssistanceCallback> gnssAssistanceCallback = + sp<gnss::GnssAssistanceCallback>::make(); + if (!gnssAssistanceIface->setCallback(gnssAssistanceCallback)) { + ALOGI("IGnssAssistanceInterface setCallback() failed"); + } + } + return JNI_TRUE; } @@ -493,6 +514,15 @@ static void android_location_gnss_hal_GnssNative_inject_psds_data(JNIEnv* env, j gnssPsdsIface->injectPsdsData(data, length, psdsType); } +static void android_location_gnss_hal_GnssNative_inject_gnss_assistance(JNIEnv* env, jclass, + jobject gnssAssistanceObj) { + if (gnssAssistanceIface == nullptr) { + ALOGE("%s: IGnssAssistance interface not available.", __func__); + return; + } + gnssAssistanceIface->injectGnssAssistance(env, gnssAssistanceObj); +} + static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open( JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) { if (apn == nullptr) { @@ -937,6 +967,8 @@ static const JNINativeMethod sLocationProviderMethods[] = { {"native_stop_nmea_message_collection", "()Z", reinterpret_cast<void*>( android_location_gnss_hal_GnssNative_stop_nmea_message_collection)}, + {"native_inject_gnss_assistance", "(Landroid/location/GnssAssistance;)V", + reinterpret_cast<void*>(android_location_gnss_hal_GnssNative_inject_gnss_assistance)}, }; static const JNINativeMethod sBatchingMethods[] = { diff --git a/services/core/jni/com_android_server_sensor_SensorService.cpp b/services/core/jni/com_android_server_sensor_SensorService.cpp index eb729de6afd4..0bee7181c2d5 100644 --- a/services/core/jni/com_android_server_sensor_SensorService.cpp +++ b/services/core/jni/com_android_server_sensor_SensorService.cpp @@ -60,6 +60,8 @@ public: void unregisterRuntimeSensor(jint handle); jboolean sendRuntimeSensorEvent(JNIEnv* env, jint handle, jint type, jlong timestamp, jfloatArray values); + jboolean sendRuntimeSensorAdditionalInfo(JNIEnv* env, jint handle, jint type, jint serial, + jlong timestamp, jfloatArray values); private: sp<SensorService> mService; @@ -172,9 +174,9 @@ jboolean NativeSensorService::sendRuntimeSensorEvent(JNIEnv* env, jint handle, j sensors_event_t event{ .version = sizeof(sensors_event_t), - .timestamp = timestamp, .sensor = handle, .type = type, + .timestamp = timestamp, }; int valuesLength = env->GetArrayLength(values); @@ -234,6 +236,42 @@ jboolean NativeSensorService::sendRuntimeSensorEvent(JNIEnv* env, jint handle, j return err == OK; } +jboolean NativeSensorService::sendRuntimeSensorAdditionalInfo(JNIEnv* env, jint handle, jint type, + jint serial, jlong timestamp, + jfloatArray values) { + if (mService == nullptr) { + ALOGD("Dropping sendRuntimeSensorAdditionalInfo, sensor service not available."); + return false; + } + + sensors_event_t event{ + .version = sizeof(sensors_event_t), + .sensor = handle, + .type = SENSOR_TYPE_ADDITIONAL_INFO, + .timestamp = timestamp, + .additional_info = + (additional_info_event_t){ + .type = type, + .serial = serial, + }, + }; + + if (values != nullptr) { + int valuesLength = env->GetArrayLength(values); + if (valuesLength > 14) { + ALOGD("Dropping sendRuntimeSensorAdditionalInfo, number of values exceeds maximum."); + return false; + } + if (valuesLength > 0) { + jfloat* sensorValues = env->GetFloatArrayElements(values, nullptr); + memcpy(event.additional_info.data_float, sensorValues, valuesLength * sizeof(float)); + } + } + + status_t err = mService->sendRuntimeSensorEvent(event); + return err == OK; +} + NativeSensorService::ProximityActiveListenerDelegate::ProximityActiveListenerDelegate( JNIEnv* env, jobject listener) : mListener(env->NewGlobalRef(listener)) {} @@ -326,6 +364,13 @@ static jboolean sendRuntimeSensorEventNative(JNIEnv* env, jclass, jlong ptr, jin return service->sendRuntimeSensorEvent(env, handle, type, timestamp, values); } +static jboolean sendRuntimeSensorAdditionalInfoNative(JNIEnv* env, jclass, jlong ptr, jint handle, + jint type, jint serial, jlong timestamp, + jfloatArray values) { + auto* service = reinterpret_cast<NativeSensorService*>(ptr); + return service->sendRuntimeSensorAdditionalInfo(env, handle, type, serial, timestamp, values); +} + static const JNINativeMethod methods[] = { {"startSensorServiceNative", "(L" PROXIMITY_ACTIVE_CLASS ";)J", reinterpret_cast<void*>(startSensorServiceNative)}, @@ -340,6 +385,8 @@ static const JNINativeMethod methods[] = { reinterpret_cast<void*>(unregisterRuntimeSensorNative)}, {"sendRuntimeSensorEventNative", "(JIIJ[F)Z", reinterpret_cast<void*>(sendRuntimeSensorEventNative)}, + {"sendRuntimeSensorAdditionalInfoNative", "(JIIIJ[F)Z", + reinterpret_cast<void*>(sendRuntimeSensorAdditionalInfoNative)}, }; int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env) { diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index e72259f094bc..562e82f90bfa 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -17,7 +17,6 @@ cc_library_shared { "-Werror", "-Wno-unused-parameter", "-Wthread-safety", - "-DEGL_EGLEXT_PROTOTYPES", "-DGL_GLEXT_PROTOTYPES", ], @@ -41,6 +40,8 @@ cc_library_shared { "GnssMeasurementCallback.cpp", "GnssNavigationMessage.cpp", "GnssNavigationMessageCallback.cpp", + "GnssAssistance.cpp", + "GnssAssistanceCallback.cpp", "GnssPsds.cpp", "GnssPsdsCallback.cpp", "GnssVisibilityControl.cpp", @@ -61,7 +62,7 @@ cc_defaults { "libnativehelper", "libhardware_legacy", "libutils", - "android.hardware.gnss-V3-cpp", + "android.hardware.gnss-V5-cpp", "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", diff --git a/services/core/jni/gnss/Gnss.cpp b/services/core/jni/gnss/Gnss.cpp index da8928b5f97f..a3fd9aa79cfb 100644 --- a/services/core/jni/gnss/Gnss.cpp +++ b/services/core/jni/gnss/Gnss.cpp @@ -765,4 +765,15 @@ sp<hardware::gnss::V1_0::IGnssNi> GnssHal::getGnssNiInterface() { return nullptr; } +std::unique_ptr<GnssAssistanceInterface> GnssHal::getGnssAssistanceInterface() { + if (gnssHalAidl != nullptr) { + sp<hardware::gnss::gnss_assistance::IGnssAssistanceInterface> gnssAssistance; + auto status = gnssHalAidl->getExtensionGnssAssistanceInterface(&gnssAssistance); + if (checkAidlStatus(status, "Unable to get a handle to GnssAssistance")) { + return std::make_unique<GnssAssistanceInterface>(gnssAssistance); + } + } + return nullptr; +} + } // namespace android::gnss diff --git a/services/core/jni/gnss/Gnss.h b/services/core/jni/gnss/Gnss.h index 458da8a6e514..2b6b7513a231 100644 --- a/services/core/jni/gnss/Gnss.h +++ b/services/core/jni/gnss/Gnss.h @@ -34,6 +34,7 @@ #include "AGnss.h" #include "AGnssRil.h" #include "GnssAntennaInfo.h" +#include "GnssAssistance.h" #include "GnssBatching.h" #include "GnssCallback.h" #include "GnssConfiguration.h" @@ -115,6 +116,7 @@ public: std::unique_ptr<GnssVisibilityControlInterface> getGnssVisibilityControlInterface(); std::unique_ptr<GnssAntennaInfoInterface> getGnssAntennaInfoInterface(); std::unique_ptr<GnssPsdsInterface> getGnssPsdsInterface(); + std::unique_ptr<GnssAssistanceInterface> getGnssAssistanceInterface(); sp<hardware::gnss::IGnssPowerIndication> getGnssPowerIndicationInterface(); sp<hardware::gnss::V1_0::IGnssNi> getGnssNiInterface(); diff --git a/services/core/jni/gnss/GnssAssistance.cpp b/services/core/jni/gnss/GnssAssistance.cpp new file mode 100644 index 000000000000..fff396ea126a --- /dev/null +++ b/services/core/jni/gnss/GnssAssistance.cpp @@ -0,0 +1,2047 @@ +/* + * Copyright (C) 2024 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. + */ + +// Define LOG_TAG before <log/log.h> to overwrite the default value. + +#define LOG_TAG "GnssAssistanceJni" + +#include "GnssAssistance.h" + +#include <utils/String16.h> + +#include "GnssAssistanceCallback.h" +#include "Utils.h" + +namespace android::gnss { + +using GnssConstellationType = android::hardware::gnss::GnssConstellationType; +using GnssCorrectionComponent = android::hardware::gnss::gnss_assistance::GnssCorrectionComponent; +using GnssInterval = + android::hardware::gnss::gnss_assistance::GnssCorrectionComponent::GnssInterval; +using GnssSatelliteAlmanac = + android::hardware::gnss::gnss_assistance::GnssAlmanac::GnssSatelliteAlmanac; +using IonosphericCorrection = android::hardware::gnss::gnss_assistance::IonosphericCorrection; +using PseudorangeCorrection = + android::hardware::gnss::gnss_assistance::GnssCorrectionComponent::PseudorangeCorrection; +using GalileoSatelliteClockModel = android::hardware::gnss::gnss_assistance:: + GalileoSatelliteEphemeris::GalileoSatelliteClockModel; +using GalileoSvHealth = + android::hardware::gnss::gnss_assistance::GalileoSatelliteEphemeris::GalileoSvHealth; +using GlonassSatelliteAlmanac = + android::hardware::gnss::gnss_assistance::GlonassAlmanac::GlonassSatelliteAlmanac; +using GlonassSatelliteClockModel = android::hardware::gnss::gnss_assistance:: + GlonassSatelliteEphemeris::GlonassSatelliteClockModel; +using GlonassSatelliteOrbitModel = android::hardware::gnss::gnss_assistance:: + GlonassSatelliteEphemeris::GlonassSatelliteOrbitModel; +using GnssSignalType = hardware::gnss::GnssSignalType; +using GnssConstellationType = hardware::gnss::GnssConstellationType; +using BeidouB1CSatelliteOrbitType = + android::hardware::gnss::gnss_assistance::AuxiliaryInformation::BeidouB1CSatelliteOrbitType; +using QzssSatelliteEphemeris = android::hardware::gnss::gnss_assistance::QzssSatelliteEphemeris; + +// Implementation of GnssAssistance (AIDL HAL) + +namespace { +jmethodID method_gnssAssistanceGetGpsAssistance; +jmethodID method_gnssAssistanceGetGlonassAssistance; +jmethodID method_gnssAssistanceGetGalileoAssistance; +jmethodID method_gnssAssistanceGetBeidouAssistance; +jmethodID method_gnssAssistanceGetQzssAssistance; + +jmethodID method_listSize; +jmethodID method_listGet; + +jmethodID method_gnssAlmanacGetIssueDateMillis; +jmethodID method_gnssAlmanacGetIoda; +jmethodID method_gnssAlmanacGetWeekNumber; +jmethodID method_gnssAlmanacGetToaSeconds; +jmethodID method_gnssAlmanacGetSatelliteAlmanacs; +jmethodID method_gnssAlmanacIsCompleteAlmanacProvided; +jmethodID method_satelliteAlmanacGetSvid; +jmethodID method_satelliteAlmanacGetSvHealth; +jmethodID method_satelliteAlmanacGetAf0; +jmethodID method_satelliteAlmanacGetAf1; +jmethodID method_satelliteAlmanacGetEccentricity; +jmethodID method_satelliteAlmanacGetInclination; +jmethodID method_satelliteAlmanacGetM0; +jmethodID method_satelliteAlmanacGetOmega; +jmethodID method_satelliteAlmanacGetOmega0; +jmethodID method_satelliteAlmanacGetOmegaDot; +jmethodID method_satelliteAlmanacGetRootA; + +jmethodID method_satelliteEphemerisTimeGetIode; +jmethodID method_satelliteEphemerisTimeGetToeSeconds; +jmethodID method_satelliteEphemerisTimeGetWeekNumber; + +jmethodID method_keplerianOrbitModelGetDeltaN; +jmethodID method_keplerianOrbitModelGetEccentricity; +jmethodID method_keplerianOrbitModelGetI0; +jmethodID method_keplerianOrbitModelGetIDot; +jmethodID method_keplerianOrbitModelGetM0; +jmethodID method_keplerianOrbitModelGetOmega; +jmethodID method_keplerianOrbitModelGetOmega0; +jmethodID method_keplerianOrbitModelGetOmegaDot; +jmethodID method_keplerianOrbitModelGetRootA; +jmethodID method_keplerianOrbitModelGetSecondOrderHarmonicPerturbation; +jmethodID method_secondOrderHarmonicPerturbationGetCic; +jmethodID method_secondOrderHarmonicPerturbationGetCis; +jmethodID method_secondOrderHarmonicPerturbationGetCrc; +jmethodID method_secondOrderHarmonicPerturbationGetCrs; +jmethodID method_secondOrderHarmonicPerturbationGetCuc; +jmethodID method_secondOrderHarmonicPerturbationGetCus; + +jmethodID method_klobucharIonosphericModelGetAlpha0; +jmethodID method_klobucharIonosphericModelGetAlpha1; +jmethodID method_klobucharIonosphericModelGetAlpha2; +jmethodID method_klobucharIonosphericModelGetAlpha3; +jmethodID method_klobucharIonosphericModelGetBeta0; +jmethodID method_klobucharIonosphericModelGetBeta1; +jmethodID method_klobucharIonosphericModelGetBeta2; +jmethodID method_klobucharIonosphericModelGetBeta3; + +jmethodID method_utcModelGetA0; +jmethodID method_utcModelGetA1; +jmethodID method_utcModelGetTimeOfWeek; +jmethodID method_utcModelGetWeekNumber; + +jmethodID method_leapSecondsModelGetDayNumberLeapSecondsFuture; +jmethodID method_leapSecondsModelGetLeapSeconds; +jmethodID method_leapSecondsModelGetLeapSecondsFuture; +jmethodID method_leapSecondsModelGetWeekNumberLeapSecondsFuture; + +jmethodID method_timeModelsGetTimeOfWeek; +jmethodID method_timeModelsGetToGnss; +jmethodID method_timeModelsGetWeekNumber; +jmethodID method_timeModelsGetA0; +jmethodID method_timeModelsGetA1; + +jmethodID method_realTimeIntegrityModelGetBadSvid; +jmethodID method_realTimeIntegrityModelGetBadSignalTypes; +jmethodID method_realTimeIntegrityModelGetStartDateSeconds; +jmethodID method_realTimeIntegrityModelGetEndDateSeconds; +jmethodID method_realTimeIntegrityModelGetPublishDateSeconds; +jmethodID method_realTimeIntegrityModelGetAdvisoryNumber; +jmethodID method_realTimeIntegrityModelGetAdvisoryType; + +jmethodID method_gnssSignalTypeGetConstellationType; +jmethodID method_gnssSignalTypeGetCarrierFrequencyHz; +jmethodID method_gnssSignalTypeGetCodeType; + +jmethodID method_auxiliaryInformationGetSvid; +jmethodID method_auxiliaryInformationGetAvailableSignalTypes; +jmethodID method_auxiliaryInformationGetFrequencyChannelNumber; +jmethodID method_auxiliaryInformationGetSatType; + +jmethodID method_satelliteCorrectionGetSvid; +jmethodID method_satelliteCorrectionGetIonosphericCorrections; +jmethodID method_ionosphericCorrectionGetCarrierFrequencyHz; +jmethodID method_ionosphericCorrectionGetIonosphericCorrection; +jmethodID method_gnssCorrectionComponentGetPseudorangeCorrection; +jmethodID method_gnssCorrectionComponentGetSourceKey; +jmethodID method_gnssCorrectionComponentGetValidityInterval; +jmethodID method_pseudorangeCorrectionGetCorrectionMeters; +jmethodID method_pseudorangeCorrectionGetCorrectionUncertaintyMeters; +jmethodID method_pseudorangeCorrectionGetCorrectionRateMetersPerSecond; +jmethodID method_gnssIntervalGetStartMillisSinceGpsEpoch; +jmethodID method_gnssIntervalGetEndMillisSinceGpsEpoch; + +jmethodID method_gpsAssistanceGetAlmanac; +jmethodID method_gpsAssistanceGetIonosphericModel; +jmethodID method_gpsAssistanceGetUtcModel; +jmethodID method_gpsAssistanceGetLeapSecondsModel; +jmethodID method_gpsAssistanceGetTimeModels; +jmethodID method_gpsAssistanceGetSatelliteEphemeris; +jmethodID method_gpsAssistanceGetRealTimeIntegrityModels; +jmethodID method_gpsAssistanceGetSatelliteCorrections; +jmethodID method_gpsSatelliteEphemerisGetSvid; +jmethodID method_gpsSatelliteEphemerisGetGpsL2Params; +jmethodID method_gpsSatelliteEphemerisGetSatelliteClockModel; +jmethodID method_gpsSatelliteEphemerisGetSatelliteOrbitModel; +jmethodID method_gpsSatelliteEphemerisGetSatelliteHealth; +jmethodID method_gpsSatelliteEphemerisGetSatelliteEphemerisTime; +jmethodID method_gpsL2ParamsGetL2Code; +jmethodID method_gpsL2ParamsGetL2Flag; +jmethodID method_gpsSatelliteClockModelGetAf0; +jmethodID method_gpsSatelliteClockModelGetAf1; +jmethodID method_gpsSatelliteClockModelGetAf2; +jmethodID method_gpsSatelliteClockModelGetTgd; +jmethodID method_gpsSatelliteClockModelGetIodc; +jmethodID method_gpsSatelliteClockModelGetTimeOfClockSeconds; +jmethodID method_gpsSatelliteHealthGetFitInt; +jmethodID method_gpsSatelliteHealthGetSvAccur; +jmethodID method_gpsSatelliteHealthGetSvHealth; + +jmethodID method_beidouAssistanceGetAlmanac; +jmethodID method_beidouAssistanceGetIonosphericModel; +jmethodID method_beidouAssistanceGetUtcModel; +jmethodID method_beidouAssistanceGetLeapSecondsModel; +jmethodID method_beidouAssistanceGetTimeModels; +jmethodID method_beidouAssistanceGetSatelliteEphemeris; +jmethodID method_beidouAssistanceGetSatelliteCorrections; +jmethodID method_beidouAssistanceGetRealTimeIntegrityModels; +jmethodID method_beidouSatelliteEphemerisGetSvid; +jmethodID method_beidouSatelliteEphemerisGetSatelliteClockModel; +jmethodID method_beidouSatelliteEphemerisGetSatelliteOrbitModel; +jmethodID method_beidouSatelliteEphemerisGetSatelliteHealth; +jmethodID method_beidouSatelliteEphemerisGetSatelliteEphemerisTime; +jmethodID method_beidouSatelliteClockModelGetAf0; +jmethodID method_beidouSatelliteClockModelGetAf1; +jmethodID method_beidouSatelliteClockModelGetAf2; +jmethodID method_beidouSatelliteClockModelGetAodc; +jmethodID method_beidouSatelliteClockModelGetTgd1; +jmethodID method_beidouSatelliteClockModelGetTgd2; +jmethodID method_beidouSatelliteClockModelGetTimeOfClockSeconds; +jmethodID method_beidouSatelliteHealthGetSatH1; +jmethodID method_beidouSatelliteHealthGetSvAccur; +jmethodID method_beidouSatelliteEphemerisTimeGetIode; +jmethodID method_beidouSatelliteEphemerisTimeGetBeidouWeekNumber; +jmethodID method_beidouSatelliteEphemerisTimeGetToeSeconds; + +jmethodID method_galileoAssistanceGetAlmanac; +jmethodID method_galileoAssistanceGetIonosphericModel; +jmethodID method_galileoAssistanceGetUtcModel; +jmethodID method_galileoAssistanceGetLeapSecondsModel; +jmethodID method_galileoAssistanceGetTimeModels; +jmethodID method_galileoAssistanceGetSatelliteEphemeris; +jmethodID method_galileoAssistanceGetSatelliteCorrections; +jmethodID method_galileoAssistanceGetRealTimeIntegrityModels; +jmethodID method_galileoSatelliteEphemerisGetSvid; +jmethodID method_galileoSatelliteEphemerisGetSatelliteClockModels; +jmethodID method_galileoSatelliteEphemerisGetSatelliteOrbitModel; +jmethodID method_galileoSatelliteEphemerisGetSatelliteHealth; +jmethodID method_galileoSatelliteEphemerisGetSatelliteEphemerisTime; +jmethodID method_galileoSatelliteClockModelGetAf0; +jmethodID method_galileoSatelliteClockModelGetAf1; +jmethodID method_galileoSatelliteClockModelGetAf2; +jmethodID method_galileoSatelliteClockModelGetBgdSeconds; +jmethodID method_galileoSatelliteClockModelGetSatelliteClockType; +jmethodID method_galileoSatelliteClockModelGetSisaMeters; +jmethodID method_galileoSatelliteClockModelGetTimeOfClockSeconds; +jmethodID method_galileoSvHealthGetDataValidityStatusE1b; +jmethodID method_galileoSvHealthGetDataValidityStatusE5a; +jmethodID method_galileoSvHealthGetDataValidityStatusE5b; +jmethodID method_galileoSvHealthGetSignalHealthStatusE1b; +jmethodID method_galileoSvHealthGetSignalHealthStatusE5a; +jmethodID method_galileoSvHealthGetSignalHealthStatusE5b; +jmethodID method_galileoIonosphericModelGetAi0; +jmethodID method_galileoIonosphericModelGetAi1; +jmethodID method_galileoIonosphericModelGetAi2; + +jmethodID method_glonassAssistanceGetAlmanac; +jmethodID method_glonassAssistanceGetUtcModel; +jmethodID method_glonassAssistanceGetTimeModels; +jmethodID method_glonassAssistanceGetSatelliteEphemeris; +jmethodID method_glonassAssistanceGetSatelliteCorrections; +jmethodID method_glonassAlmanacGetIssueDateMillis; +jmethodID method_glonassAlmanacGetSatelliteAlmanacs; +jmethodID method_glonassSatelliteAlmanacGetDeltaI; +jmethodID method_glonassSatelliteAlmanacGetDeltaT; +jmethodID method_glonassSatelliteAlmanacGetDeltaTDot; +jmethodID method_glonassSatelliteAlmanacGetEccentricity; +jmethodID method_glonassSatelliteAlmanacGetFrequencyChannelNumber; +jmethodID method_glonassSatelliteAlmanacGetLambda; +jmethodID method_glonassSatelliteAlmanacGetOmega; +jmethodID method_glonassSatelliteAlmanacGetSlotNumber; +jmethodID method_glonassSatelliteAlmanacGetHealthState; +jmethodID method_glonassSatelliteAlmanacGetTLambda; +jmethodID method_glonassSatelliteAlmanacGetTau; +jmethodID method_glonassSatelliteAlmanacGetIsGlonassM; +jmethodID method_glonassSatelliteAlmanacGetCalendarDayNumber; +jmethodID method_glonassSatelliteEphemerisGetAgeInDays; +jmethodID method_glonassSatelliteEphemerisGetSatelliteClockModel; +jmethodID method_glonassSatelliteEphemerisGetSatelliteOrbitModel; +jmethodID method_glonassSatelliteEphemerisGetHealthState; +jmethodID method_glonassSatelliteEphemerisGetSlotNumber; +jmethodID method_glonassSatelliteEphemerisGetFrameTimeSeconds; +jmethodID method_glonassSatelliteEphemerisGetUpdateIntervalMinutes; +jmethodID method_glonassSatelliteEphemerisGetIsGlonassM; +jmethodID method_glonassSatelliteEphemerisGetIsUpdateIntervalOdd; + +jmethodID method_glonassSatelliteOrbitModelGetX; +jmethodID method_glonassSatelliteOrbitModelGetY; +jmethodID method_glonassSatelliteOrbitModelGetZ; +jmethodID method_glonassSatelliteOrbitModelGetXAccel; +jmethodID method_glonassSatelliteOrbitModelGetYAccel; +jmethodID method_glonassSatelliteOrbitModelGetZAccel; +jmethodID method_glonassSatelliteOrbitModelGetXDot; +jmethodID method_glonassSatelliteOrbitModelGetYDot; +jmethodID method_glonassSatelliteOrbitModelGetZDot; +jmethodID method_glonassSatelliteClockModelGetClockBias; +jmethodID method_glonassSatelliteClockModelGetFrequencyBias; +jmethodID method_glonassSatelliteClockModelGetFrequencyChannelNumber; +jmethodID method_glonassSatelliteClockModelGetTimeOfClockSeconds; + +jmethodID method_qzssAssistanceGetAlmanac; +jmethodID method_qzssAssistanceGetIonosphericModel; +jmethodID method_qzssAssistanceGetUtcModel; +jmethodID method_qzssAssistanceGetLeapSecondsModel; +jmethodID method_qzssAssistanceGetTimeModels; +jmethodID method_qzssAssistanceGetSatelliteEphemeris; +jmethodID method_qzssAssistanceGetSatelliteCorrections; +jmethodID method_qzssAssistanceGetRealTimeIntegrityModels; +jmethodID method_qzssSatelliteEphemerisGetSvid; +jmethodID method_qzssSatelliteEphemerisGetGpsL2Params; +jmethodID method_qzssSatelliteEphemerisGetSatelliteClockModel; +jmethodID method_qzssSatelliteEphemerisGetSatelliteOrbitModel; +jmethodID method_qzssSatelliteEphemerisGetSatelliteHealth; +jmethodID method_qzssSatelliteEphemerisGetSatelliteEphemerisTime; +jmethodID method_qzssSatelliteClockModelGetAf0; +jmethodID method_qzssSatelliteClockModelGetAf1; +jmethodID method_qzssSatelliteClockModelGetAf2; +jmethodID method_qzssSatelliteClockModelGetAodc; +jmethodID method_qzssSatelliteClockModelGetTgd1; +jmethodID method_qzssSatelliteClockModelGetTgd2; +jmethodID method_qzssSatelliteClockModelGetTimeOfClockSeconds; +} // namespace + +void GnssAssistance_class_init_once(JNIEnv* env, jclass clazz) { + // Get the methods of GnssAssistance class. + jclass gnssAssistanceClass = env->FindClass("android/location/GnssAssistance"); + + method_gnssAssistanceGetGpsAssistance = + env->GetMethodID(gnssAssistanceClass, "getGpsAssistance", + "()Landroid/location/GpsAssistance;"); + method_gnssAssistanceGetGlonassAssistance = + env->GetMethodID(gnssAssistanceClass, "getGlonassAssistance", + "()Landroid/location/GlonassAssistance;"); + method_gnssAssistanceGetGalileoAssistance = + env->GetMethodID(gnssAssistanceClass, "getGalileoAssistance", + "()Landroid/location/GalileoAssistance;"); + method_gnssAssistanceGetBeidouAssistance = + env->GetMethodID(gnssAssistanceClass, "getBeidouAssistance", + "()Landroid/location/BeidouAssistance;"); + method_gnssAssistanceGetQzssAssistance = + env->GetMethodID(gnssAssistanceClass, "getQzssAssistance", + "()Landroid/location/QzssAssistance;"); + + // Get the methods of List class. + jclass listClass = env->FindClass("java/util/List"); + + method_listSize = env->GetMethodID(listClass, "size", "()I"); + method_listGet = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;"); + + // Get the methods of GnssAlmanac class. + jclass gnssAlmanacClass = env->FindClass("android/location/GnssAlmanac"); + + method_gnssAlmanacGetIssueDateMillis = + env->GetMethodID(gnssAlmanacClass, "getIssueDateMillis", "()J"); + method_gnssAlmanacGetIoda = env->GetMethodID(gnssAlmanacClass, "getIoda", "()I"); + method_gnssAlmanacGetWeekNumber = env->GetMethodID(gnssAlmanacClass, "getWeekNumber", "()I"); + method_gnssAlmanacGetToaSeconds = env->GetMethodID(gnssAlmanacClass, "getToaSeconds", "()I"); + method_gnssAlmanacGetSatelliteAlmanacs = + env->GetMethodID(gnssAlmanacClass, "getGnssSatelliteAlmanacs", "()Ljava/util/List;"); + method_gnssAlmanacIsCompleteAlmanacProvided = + env->GetMethodID(gnssAlmanacClass, "isCompleteAlmanacProvided", "()Z"); + + // Get the methods of SatelliteAlmanac class. + jclass satelliteAlmanacClass = + env->FindClass("android/location/GnssAlmanac$GnssSatelliteAlmanac"); + + method_satelliteAlmanacGetSvid = env->GetMethodID(satelliteAlmanacClass, "getSvid", "()I"); + method_satelliteAlmanacGetSvHealth = + env->GetMethodID(satelliteAlmanacClass, "getSvHealth", "()I"); + method_satelliteAlmanacGetAf0 = env->GetMethodID(satelliteAlmanacClass, "getAf0", "()D"); + method_satelliteAlmanacGetAf1 = env->GetMethodID(satelliteAlmanacClass, "getAf1", "()D"); + method_satelliteAlmanacGetEccentricity = + env->GetMethodID(satelliteAlmanacClass, "getEccentricity", "()D"); + method_satelliteAlmanacGetInclination = + env->GetMethodID(satelliteAlmanacClass, "getInclination", "()D"); + method_satelliteAlmanacGetM0 = env->GetMethodID(satelliteAlmanacClass, "getM0", "()D"); + method_satelliteAlmanacGetOmega = env->GetMethodID(satelliteAlmanacClass, "getOmega", "()D"); + method_satelliteAlmanacGetOmega0 = env->GetMethodID(satelliteAlmanacClass, "getOmega0", "()D"); + method_satelliteAlmanacGetOmegaDot = + env->GetMethodID(satelliteAlmanacClass, "getOmegaDot", "()D"); + method_satelliteAlmanacGetRootA = env->GetMethodID(satelliteAlmanacClass, "getRootA", "()D"); + + // Get the mothods of SatelliteEphemerisTime class. + jclass satelliteEphemerisTimeClass = env->FindClass("android/location/SatelliteEphemerisTime"); + + method_satelliteEphemerisTimeGetIode = + env->GetMethodID(satelliteEphemerisTimeClass, "getIode", "()I"); + method_satelliteEphemerisTimeGetToeSeconds = + env->GetMethodID(satelliteEphemerisTimeClass, "getToeSeconds", "()I"); + method_satelliteEphemerisTimeGetWeekNumber = + env->GetMethodID(satelliteEphemerisTimeClass, "getWeekNumber", "()I"); + + // Get the mothods of KeplerianOrbitModel class. + jclass keplerianOrbitModelClass = env->FindClass("android/location/KeplerianOrbitModel"); + + method_keplerianOrbitModelGetDeltaN = + env->GetMethodID(keplerianOrbitModelClass, "getDeltaN", "()D"); + method_keplerianOrbitModelGetEccentricity = + env->GetMethodID(keplerianOrbitModelClass, "getEccentricity", "()D"); + method_keplerianOrbitModelGetI0 = env->GetMethodID(keplerianOrbitModelClass, "getI0", "()D"); + method_keplerianOrbitModelGetIDot = + env->GetMethodID(keplerianOrbitModelClass, "getIDot", "()D"); + method_keplerianOrbitModelGetM0 = env->GetMethodID(keplerianOrbitModelClass, "getM0", "()D"); + method_keplerianOrbitModelGetOmega = + env->GetMethodID(keplerianOrbitModelClass, "getOmega", "()D"); + method_keplerianOrbitModelGetOmega0 = + env->GetMethodID(keplerianOrbitModelClass, "getOmega0", "()D"); + method_keplerianOrbitModelGetOmegaDot = + env->GetMethodID(keplerianOrbitModelClass, "getOmegaDot", "()D"); + method_keplerianOrbitModelGetRootA = + env->GetMethodID(keplerianOrbitModelClass, "getRootA", "()D"); + method_keplerianOrbitModelGetSecondOrderHarmonicPerturbation = + env->GetMethodID(keplerianOrbitModelClass, "getSecondOrderHarmonicPerturbation", + "()Landroid/location/" + "KeplerianOrbitModel$SecondOrderHarmonicPerturbation;"); + + // Get the methods of SecondOrderHarmonicPerturbation class. + jclass secondOrderHarmonicPerturbationClass = + env->FindClass("android/location/KeplerianOrbitModel$SecondOrderHarmonicPerturbation"); + + method_secondOrderHarmonicPerturbationGetCic = + env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCic", "()D"); + method_secondOrderHarmonicPerturbationGetCis = + env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCis", "()D"); + method_secondOrderHarmonicPerturbationGetCrc = + env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCrc", "()D"); + method_secondOrderHarmonicPerturbationGetCrs = + env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCrs", "()D"); + method_secondOrderHarmonicPerturbationGetCuc = + env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCuc", "()D"); + method_secondOrderHarmonicPerturbationGetCus = + env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCus", "()D"); + + // Get the methods of KlobucharIonosphericModel class. + jclass klobucharIonosphericModelClass = + env->FindClass("android/location/KlobucharIonosphericModel"); + + method_klobucharIonosphericModelGetAlpha0 = + env->GetMethodID(klobucharIonosphericModelClass, "getAlpha0", "()D"); + method_klobucharIonosphericModelGetAlpha1 = + env->GetMethodID(klobucharIonosphericModelClass, "getAlpha1", "()D"); + method_klobucharIonosphericModelGetAlpha2 = + env->GetMethodID(klobucharIonosphericModelClass, "getAlpha2", "()D"); + method_klobucharIonosphericModelGetAlpha3 = + env->GetMethodID(klobucharIonosphericModelClass, "getAlpha3", "()D"); + method_klobucharIonosphericModelGetBeta0 = + env->GetMethodID(klobucharIonosphericModelClass, "getBeta0", "()D"); + method_klobucharIonosphericModelGetBeta1 = + env->GetMethodID(klobucharIonosphericModelClass, "getBeta1", "()D"); + method_klobucharIonosphericModelGetBeta2 = + env->GetMethodID(klobucharIonosphericModelClass, "getBeta2", "()D"); + method_klobucharIonosphericModelGetBeta3 = + env->GetMethodID(klobucharIonosphericModelClass, "getBeta3", "()D"); + + // Get the methods of UtcModel class. + jclass utcModelClass = env->FindClass("android/location/UtcModel"); + + method_utcModelGetA0 = env->GetMethodID(utcModelClass, "getA0", "()D"); + method_utcModelGetA1 = env->GetMethodID(utcModelClass, "getA1", "()D"); + method_utcModelGetTimeOfWeek = env->GetMethodID(utcModelClass, "getTimeOfWeek", "()I"); + method_utcModelGetWeekNumber = env->GetMethodID(utcModelClass, "getWeekNumber", "()I"); + + // Get the methods of LeapSecondsModel class. + jclass leapSecondsModelClass = env->FindClass("android/location/LeapSecondsModel"); + + method_leapSecondsModelGetDayNumberLeapSecondsFuture = + env->GetMethodID(leapSecondsModelClass, "getDayNumberLeapSecondsFuture", "()I"); + method_leapSecondsModelGetLeapSeconds = + env->GetMethodID(leapSecondsModelClass, "getLeapSeconds", "()I"); + method_leapSecondsModelGetLeapSecondsFuture = + env->GetMethodID(leapSecondsModelClass, "getLeapSecondsFuture", "()I"); + method_leapSecondsModelGetWeekNumberLeapSecondsFuture = + env->GetMethodID(leapSecondsModelClass, "getWeekNumberLeapSecondsFuture", "()I"); + + // Get the methods of TimeModel class. + jclass timeModelsClass = env->FindClass("android/location/TimeModel"); + + method_timeModelsGetTimeOfWeek = env->GetMethodID(timeModelsClass, "getTimeOfWeek", "()I"); + method_timeModelsGetToGnss = env->GetMethodID(timeModelsClass, "getToGnss", "()I"); + method_timeModelsGetWeekNumber = env->GetMethodID(timeModelsClass, "getWeekNumber", "()I"); + method_timeModelsGetA0 = env->GetMethodID(timeModelsClass, "getA0", "()D"); + method_timeModelsGetA1 = env->GetMethodID(timeModelsClass, "getA1", "()D"); + + // Get the methods of AuxiliaryInformation class. + jclass auxiliaryInformationClass = env->FindClass("android/location/AuxiliaryInformation"); + + method_auxiliaryInformationGetSvid = + env->GetMethodID(auxiliaryInformationClass, "getSvid", "()I"); + method_auxiliaryInformationGetAvailableSignalTypes = + env->GetMethodID(auxiliaryInformationClass, "getAvailableSignalTypes", + "()Ljava/util/List;"); + method_auxiliaryInformationGetFrequencyChannelNumber = + env->GetMethodID(auxiliaryInformationClass, "getFrequencyChannelNumber", "()I"); + method_auxiliaryInformationGetSatType = + env->GetMethodID(auxiliaryInformationClass, "getSatType", "()I"); + + // Get the methods of RealTimeIntegrityModel + jclass realTimeIntegrityModelClass = env->FindClass("android/location/RealTimeIntegrityModel"); + + method_realTimeIntegrityModelGetBadSvid = + env->GetMethodID(realTimeIntegrityModelClass, "getBadSvid", "()I"); + method_realTimeIntegrityModelGetBadSignalTypes = + env->GetMethodID(realTimeIntegrityModelClass, "getBadSignalTypes", + "()Ljava/util/List;"); + method_realTimeIntegrityModelGetStartDateSeconds = + env->GetMethodID(realTimeIntegrityModelClass, "getStartDateSeconds", "()J"); + method_realTimeIntegrityModelGetEndDateSeconds = + env->GetMethodID(realTimeIntegrityModelClass, "getEndDateSeconds", "()J"); + method_realTimeIntegrityModelGetPublishDateSeconds = + env->GetMethodID(realTimeIntegrityModelClass, "getPublishDateSeconds", "()J"); + method_realTimeIntegrityModelGetAdvisoryNumber = + env->GetMethodID(realTimeIntegrityModelClass, "getAdvisoryNumber", + "()Ljava/lang/String;"); + method_realTimeIntegrityModelGetAdvisoryType = + env->GetMethodID(realTimeIntegrityModelClass, "getAdvisoryType", + "()Ljava/lang/String;"); + + // Get the methods of GnssSignalType class. + jclass gnssSignalTypeClass = env->FindClass("android/location/GnssSignalType"); + + method_gnssSignalTypeGetConstellationType = + env->GetMethodID(gnssSignalTypeClass, "getConstellationType", "()I"); + method_gnssSignalTypeGetCarrierFrequencyHz = + env->GetMethodID(gnssSignalTypeClass, "getCarrierFrequencyHz", "()D"); + method_gnssSignalTypeGetCodeType = + env->GetMethodID(gnssSignalTypeClass, "getCodeType", "()Ljava/lang/String;"); + + // Get the methods of SatelliteCorrection class. + jclass satelliteCorrectionClass = + env->FindClass("android/location/GnssAssistance$GnssSatelliteCorrections"); + + method_satelliteCorrectionGetSvid = + env->GetMethodID(satelliteCorrectionClass, "getSvid", "()I"); + method_satelliteCorrectionGetIonosphericCorrections = + env->GetMethodID(satelliteCorrectionClass, "getIonosphericCorrections", + "()Ljava/util/List;"); + + // Get the methods of IonosphericCorrection class. + jclass ionosphericCorrectionClass = env->FindClass("android/location/IonosphericCorrection"); + + method_ionosphericCorrectionGetCarrierFrequencyHz = + env->GetMethodID(ionosphericCorrectionClass, "getCarrierFrequencyHz", "()J"); + method_ionosphericCorrectionGetIonosphericCorrection = + env->GetMethodID(ionosphericCorrectionClass, "getIonosphericCorrection", + "()Landroid/location/GnssCorrectionComponent;"); + + // Get the methods of GnssCorrectionComponent class. + jclass gnssCorrectionComponentClass = + env->FindClass("android/location/GnssCorrectionComponent"); + + method_gnssCorrectionComponentGetPseudorangeCorrection = + env->GetMethodID(gnssCorrectionComponentClass, "getPseudorangeCorrection", + "()Landroid/location/GnssCorrectionComponent$PseudorangeCorrection;"); + method_gnssCorrectionComponentGetSourceKey = + env->GetMethodID(gnssCorrectionComponentClass, "getSourceKey", "()Ljava/lang/String;"); + method_gnssCorrectionComponentGetValidityInterval = + env->GetMethodID(gnssCorrectionComponentClass, "getValidityInterval", + "()Landroid/location/GnssCorrectionComponent$GnssInterval;"); + + // Get the methods of PseudorangeCorrection class. + jclass pseudorangeCorrectionClass = + env->FindClass("android/location/GnssCorrectionComponent$PseudorangeCorrection"); + + method_pseudorangeCorrectionGetCorrectionMeters = + env->GetMethodID(pseudorangeCorrectionClass, "getCorrectionMeters", "()D"); + method_pseudorangeCorrectionGetCorrectionRateMetersPerSecond = + env->GetMethodID(pseudorangeCorrectionClass, "getCorrectionRateMetersPerSecond", "()D"); + method_pseudorangeCorrectionGetCorrectionUncertaintyMeters = + env->GetMethodID(pseudorangeCorrectionClass, "getCorrectionUncertaintyMeters", "()D"); + + // Get the methods of GnssInterval class. + jclass gnssIntervalClass = + env->FindClass("android/location/GnssCorrectionComponent$GnssInterval"); + + method_gnssIntervalGetStartMillisSinceGpsEpoch = + env->GetMethodID(gnssIntervalClass, "getStartMillisSinceGpsEpoch", "()J"); + method_gnssIntervalGetEndMillisSinceGpsEpoch = + env->GetMethodID(gnssIntervalClass, "getEndMillisSinceGpsEpoch", "()J"); + + // Get the methods of GpsAssistance class. + jclass gpsAssistanceClass = env->FindClass("android/location/GpsAssistance"); + + method_gpsAssistanceGetAlmanac = + env->GetMethodID(gpsAssistanceClass, "getAlmanac", "()Landroid/location/GnssAlmanac;"); + method_gpsAssistanceGetIonosphericModel = + env->GetMethodID(gpsAssistanceClass, "getIonosphericModel", + "()Landroid/location/KlobucharIonosphericModel;"); + method_gpsAssistanceGetUtcModel = + env->GetMethodID(gpsAssistanceClass, "getUtcModel", "()Landroid/location/UtcModel;"); + method_gpsAssistanceGetLeapSecondsModel = + env->GetMethodID(gpsAssistanceClass, "getLeapSecondsModel", + "()Landroid/location/LeapSecondsModel;"); + method_gpsAssistanceGetTimeModels = + env->GetMethodID(gpsAssistanceClass, "getTimeModels", "()Ljava/util/List;"); + method_gpsAssistanceGetSatelliteEphemeris = + env->GetMethodID(gpsAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;"); + method_gpsAssistanceGetRealTimeIntegrityModels = + env->GetMethodID(gpsAssistanceClass, "getRealTimeIntegrityModels", + "()Ljava/util/List;"); + method_gpsAssistanceGetSatelliteCorrections = + env->GetMethodID(gpsAssistanceClass, "getSatelliteCorrections", "()Ljava/util/List;"); + + // Get the methods of GpsSatelliteEphemeris class. + jclass gpsSatelliteEphemerisClass = env->FindClass("android/location/GpsSatelliteEphemeris"); + + method_gpsSatelliteEphemerisGetSvid = + env->GetMethodID(gpsSatelliteEphemerisClass, "getSvid", "()I"); + method_gpsSatelliteEphemerisGetGpsL2Params = + env->GetMethodID(gpsSatelliteEphemerisClass, "getGpsL2Params", + "()Landroid/location/GpsSatelliteEphemeris$GpsL2Params;"); + method_gpsSatelliteEphemerisGetSatelliteClockModel = + env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteClockModel", + "()Landroid/location/GpsSatelliteEphemeris$GpsSatelliteClockModel;"); + method_gpsSatelliteEphemerisGetSatelliteOrbitModel = + env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteOrbitModel", + "()Landroid/location/KeplerianOrbitModel;"); + method_gpsSatelliteEphemerisGetSatelliteHealth = + env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteHealth", + "()Landroid/location/GpsSatelliteEphemeris$GpsSatelliteHealth;"); + method_gpsSatelliteEphemerisGetSatelliteEphemerisTime = + env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteEphemerisTime", + "()Landroid/location/SatelliteEphemerisTime;"); + + // Get the methods of GpsL2Params class. + jclass gpsL2ParamsClass = env->FindClass("android/location/GpsSatelliteEphemeris$GpsL2Params"); + method_gpsL2ParamsGetL2Code = env->GetMethodID(gpsL2ParamsClass, "getL2Code", "()I"); + method_gpsL2ParamsGetL2Flag = env->GetMethodID(gpsL2ParamsClass, "getL2Flag", "()I"); + + // Get the methods of GpsSatelliteClockModel class. + jclass gpsSatelliteClockModelClass = + env->FindClass("android/location/GpsSatelliteEphemeris$GpsSatelliteClockModel"); + method_gpsSatelliteClockModelGetAf0 = + env->GetMethodID(gpsSatelliteClockModelClass, "getAf0", "()D"); + method_gpsSatelliteClockModelGetAf1 = + env->GetMethodID(gpsSatelliteClockModelClass, "getAf1", "()D"); + method_gpsSatelliteClockModelGetAf2 = + env->GetMethodID(gpsSatelliteClockModelClass, "getAf2", "()D"); + method_gpsSatelliteClockModelGetTgd = + env->GetMethodID(gpsSatelliteClockModelClass, "getTgd", "()D"); + method_gpsSatelliteClockModelGetIodc = + env->GetMethodID(gpsSatelliteClockModelClass, "getIodc", "()I"); + method_gpsSatelliteClockModelGetTimeOfClockSeconds = + env->GetMethodID(gpsSatelliteClockModelClass, "getTimeOfClockSeconds", "()J"); + + // Get the methods of GpsSatelliteHealth class. + jclass gpsSatelliteHealthClass = + env->FindClass("android/location/GpsSatelliteEphemeris$GpsSatelliteHealth"); + method_gpsSatelliteHealthGetFitInt = + env->GetMethodID(gpsSatelliteHealthClass, "getFitInt", "()D"); + method_gpsSatelliteHealthGetSvAccur = + env->GetMethodID(gpsSatelliteHealthClass, "getSvAccur", "()D"); + method_gpsSatelliteHealthGetSvHealth = + env->GetMethodID(gpsSatelliteHealthClass, "getSvHealth", "()I"); + + // Get the methods of BeidouAssistance class. + jclass beidouAssistanceClass = env->FindClass("android/location/BeidouAssistance"); + method_beidouAssistanceGetAlmanac = env->GetMethodID(beidouAssistanceClass, "getAlmanac", + "()Landroid/location/GnssAlmanac;"); + method_beidouAssistanceGetIonosphericModel = + env->GetMethodID(beidouAssistanceClass, "getIonosphericModel", + "()Landroid/location/KlobucharIonosphericModel;"); + method_beidouAssistanceGetUtcModel = + env->GetMethodID(beidouAssistanceClass, "getUtcModel", "()Landroid/location/UtcModel;"); + method_beidouAssistanceGetLeapSecondsModel = + env->GetMethodID(beidouAssistanceClass, "getLeapSecondsModel", + "()Landroid/location/LeapSecondsModel;"); + method_beidouAssistanceGetTimeModels = + env->GetMethodID(beidouAssistanceClass, "getTimeModels", "()Ljava/util/List;"); + method_beidouAssistanceGetSatelliteEphemeris = + env->GetMethodID(beidouAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;"); + method_beidouAssistanceGetSatelliteCorrections = + env->GetMethodID(beidouAssistanceClass, "getSatelliteCorrections", + "()Ljava/util/List;"); + method_beidouAssistanceGetRealTimeIntegrityModels = + env->GetMethodID(beidouAssistanceClass, "getRealTimeIntegrityModels", + "()Ljava/util/List;"); + + // Get the methods of BeidouSatelliteEphemeris class. + jclass beidouSatelliteEphemerisClass = + env->FindClass("android/location/BeidouSatelliteEphemeris"); + method_beidouSatelliteEphemerisGetSvid = + env->GetMethodID(beidouSatelliteEphemerisClass, "getSvid", "()I"); + method_beidouSatelliteEphemerisGetSatelliteClockModel = + env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteClockModel", + "()Landroid/location/" + "BeidouSatelliteEphemeris$BeidouSatelliteClockModel;"); + method_beidouSatelliteEphemerisGetSatelliteOrbitModel = + env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteOrbitModel", + "()Landroid/location/KeplerianOrbitModel;"); + method_beidouSatelliteEphemerisGetSatelliteHealth = + env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteHealth", + "()Landroid/location/BeidouSatelliteEphemeris$BeidouSatelliteHealth;"); + method_beidouSatelliteEphemerisGetSatelliteEphemerisTime = + env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteEphemerisTime", + "()Landroid/location/" + "BeidouSatelliteEphemeris$BeidouSatelliteEphemerisTime;"); + + // Get the methods of BeidouSatelliteClockModel + jclass beidouSatelliteClockModelClass = + env->FindClass("android/location/BeidouSatelliteEphemeris$BeidouSatelliteClockModel"); + method_beidouSatelliteClockModelGetAf0 = + env->GetMethodID(beidouSatelliteClockModelClass, "getAf0", "()D"); + method_beidouSatelliteClockModelGetAf1 = + env->GetMethodID(beidouSatelliteClockModelClass, "getAf1", "()D"); + method_beidouSatelliteClockModelGetAf2 = + env->GetMethodID(beidouSatelliteClockModelClass, "getAf2", "()D"); + method_beidouSatelliteClockModelGetAodc = + env->GetMethodID(beidouSatelliteClockModelClass, "getAodc", "()I"); + method_beidouSatelliteClockModelGetTgd1 = + env->GetMethodID(beidouSatelliteClockModelClass, "getTgd1", "()D"); + method_beidouSatelliteClockModelGetTgd2 = + env->GetMethodID(beidouSatelliteClockModelClass, "getTgd2", "()D"); + method_beidouSatelliteClockModelGetTimeOfClockSeconds = + env->GetMethodID(beidouSatelliteClockModelClass, "getTimeOfClockSeconds", "()J"); + + // Get the methods of BeidouSatelliteHealth + jclass beidouSatelliteHealthClass = + env->FindClass("android/location/BeidouSatelliteEphemeris$BeidouSatelliteHealth"); + method_beidouSatelliteHealthGetSatH1 = + env->GetMethodID(beidouSatelliteHealthClass, "getSatH1", "()I"); + method_beidouSatelliteHealthGetSvAccur = + env->GetMethodID(beidouSatelliteHealthClass, "getSvAccur", "()D"); + + // Get the methods of BeidouSatelliteEphemerisTime + jclass beidouSatelliteEphemerisTimeClass = env->FindClass( + "android/location/BeidouSatelliteEphemeris$BeidouSatelliteEphemerisTime"); + method_beidouSatelliteEphemerisTimeGetIode = + env->GetMethodID(beidouSatelliteEphemerisTimeClass, "getIode", "()I"); + method_beidouSatelliteEphemerisTimeGetBeidouWeekNumber = + env->GetMethodID(beidouSatelliteEphemerisTimeClass, "getBeidouWeekNumber", "()I"); + method_beidouSatelliteEphemerisTimeGetToeSeconds = + env->GetMethodID(beidouSatelliteEphemerisTimeClass, "getToeSeconds", "()I"); + + // Get the methods of GalileoAssistance class. + jclass galileoAssistanceClass = env->FindClass("android/location/GalileoAssistance"); + method_galileoAssistanceGetAlmanac = env->GetMethodID(galileoAssistanceClass, "getAlmanac", + "()Landroid/location/GnssAlmanac;"); + method_galileoAssistanceGetIonosphericModel = + env->GetMethodID(galileoAssistanceClass, "getIonosphericModel", + "()Landroid/location/KlobucharIonosphericModel;"); + method_galileoAssistanceGetUtcModel = env->GetMethodID(galileoAssistanceClass, "getUtcModel", + "()Landroid/location/UtcModel;"); + method_galileoAssistanceGetLeapSecondsModel = + env->GetMethodID(galileoAssistanceClass, "getLeapSecondsModel", + "()Landroid/location/LeapSecondsModel;"); + method_galileoAssistanceGetTimeModels = + env->GetMethodID(galileoAssistanceClass, "getTimeModels", "()Ljava/util/List;"); + method_galileoAssistanceGetSatelliteEphemeris = + env->GetMethodID(galileoAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;"); + method_galileoAssistanceGetSatelliteCorrections = + env->GetMethodID(galileoAssistanceClass, "getSatelliteCorrections", + "()Ljava/util/List;"); + method_galileoAssistanceGetRealTimeIntegrityModels = + env->GetMethodID(galileoAssistanceClass, "getRealTimeIntegrityModels", + "()Ljava/util/List;"); + + // Get the methods of GalileoSatelliteEphemeris class + jclass galileoSatelliteEphemerisClass = + env->FindClass("android/location/GalileoSatelliteEphemeris"); + method_galileoSatelliteEphemerisGetSatelliteClockModels = + env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteClockModels", + "()Ljava/util/List;"); + method_galileoSatelliteEphemerisGetSvid = + env->GetMethodID(galileoSatelliteEphemerisClass, "getSvid", "()I"); + method_galileoSatelliteEphemerisGetSatelliteEphemerisTime = + env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteEphemerisTime", + "()Landroid/location/SatelliteEphemerisTime;"); + method_galileoSatelliteEphemerisGetSatelliteHealth = + env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteHealth", + "()Landroid/location/GalileoSatelliteEphemeris$GalileoSvHealth;"); + method_galileoSatelliteEphemerisGetSatelliteOrbitModel = + env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteOrbitModel", + "()Landroid/location/KeplerianOrbitModel;"); + + // Get the methods of GalileoSatelliteClockModel class. + jclass galileoSatelliteClockModelClass = + env->FindClass("android/location/GalileoSatelliteEphemeris$GalileoSatelliteClockModel"); + method_galileoSatelliteClockModelGetAf0 = + env->GetMethodID(galileoSatelliteClockModelClass, "getAf0", "()D"); + method_galileoSatelliteClockModelGetAf1 = + env->GetMethodID(galileoSatelliteClockModelClass, "getAf1", "()D"); + method_galileoSatelliteClockModelGetAf2 = + env->GetMethodID(galileoSatelliteClockModelClass, "getAf2", "()D"); + method_galileoSatelliteClockModelGetBgdSeconds = + env->GetMethodID(galileoSatelliteClockModelClass, "getBgdSeconds", "()D"); + method_galileoSatelliteClockModelGetSatelliteClockType = + env->GetMethodID(galileoSatelliteClockModelClass, "getSatelliteClockType", "()I"); + method_galileoSatelliteClockModelGetSisaMeters = + env->GetMethodID(galileoSatelliteClockModelClass, "getSisaMeters", "()D"); + method_galileoSatelliteClockModelGetTimeOfClockSeconds = + env->GetMethodID(galileoSatelliteClockModelClass, "getTimeOfClockSeconds", "()J"); + + // Get the methods of GalileoSvHealth class. + jclass galileoSvHealthClass = + env->FindClass("android/location/GalileoSatelliteEphemeris$GalileoSvHealth"); + method_galileoSvHealthGetDataValidityStatusE1b = + env->GetMethodID(galileoSvHealthClass, "getDataValidityStatusE1b", "()I"); + method_galileoSvHealthGetDataValidityStatusE5a = + env->GetMethodID(galileoSvHealthClass, "getDataValidityStatusE5a", "()I"); + method_galileoSvHealthGetDataValidityStatusE5b = + env->GetMethodID(galileoSvHealthClass, "getDataValidityStatusE5b", "()I"); + method_galileoSvHealthGetSignalHealthStatusE1b = + env->GetMethodID(galileoSvHealthClass, "getSignalHealthStatusE1b", "()I"); + method_galileoSvHealthGetSignalHealthStatusE5a = + env->GetMethodID(galileoSvHealthClass, "getSignalHealthStatusE5a", "()I"); + method_galileoSvHealthGetSignalHealthStatusE5b = + env->GetMethodID(galileoSvHealthClass, "getSignalHealthStatusE5b", "()I"); + + // Get the methods of GalileoIonosphericModel class. + jclass galileoIonosphericModelClass = + env->FindClass("android/location/GalileoIonosphericModel"); + method_galileoIonosphericModelGetAi0 = + env->GetMethodID(galileoIonosphericModelClass, "getAi0", "()D"); + method_galileoIonosphericModelGetAi1 = + env->GetMethodID(galileoIonosphericModelClass, "getAi1", "()D"); + method_galileoIonosphericModelGetAi2 = + env->GetMethodID(galileoIonosphericModelClass, "getAi2", "()D"); + + // Get the methods of GlonassAssistance class. + jclass glonassAssistanceClass = env->FindClass("android/location/GlonassAssistance"); + method_glonassAssistanceGetAlmanac = env->GetMethodID(glonassAssistanceClass, "getAlmanac", + "()Landroid/location/GlonassAlmanac;"); + method_glonassAssistanceGetUtcModel = env->GetMethodID(glonassAssistanceClass, "getUtcModel", + "()Landroid/location/UtcModel;"); + method_glonassAssistanceGetTimeModels = + env->GetMethodID(glonassAssistanceClass, "getTimeModels", "()Ljava/util/List;"); + method_glonassAssistanceGetSatelliteEphemeris = + env->GetMethodID(glonassAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;"); + method_glonassAssistanceGetSatelliteCorrections = + env->GetMethodID(glonassAssistanceClass, "getSatelliteCorrections", + "()Ljava/util/List;"); + + // Get the methods of GlonassAlmanac class. + jclass glonassAlmanacClass = env->FindClass("android/location/GlonassAlmanac"); + method_glonassAlmanacGetIssueDateMillis = + env->GetMethodID(glonassAlmanacClass, "getIssueDateMillis", "()J"); + method_glonassAlmanacGetSatelliteAlmanacs = + env->GetMethodID(glonassAlmanacClass, "getSatelliteAlmanacs", "()Ljava/util/List;"); + + // Get the methods of GlonassSatelliteAlmanac class + jclass glonassSatelliteAlmanacClass = + env->FindClass("android/location/GlonassAlmanac$GlonassSatelliteAlmanac"); + method_glonassSatelliteAlmanacGetDeltaI = + env->GetMethodID(glonassSatelliteAlmanacClass, "getDeltaI", "()D"); + method_glonassSatelliteAlmanacGetDeltaT = + env->GetMethodID(glonassSatelliteAlmanacClass, "getDeltaT", "()D"); + method_glonassSatelliteAlmanacGetDeltaTDot = + env->GetMethodID(glonassSatelliteAlmanacClass, "getDeltaTDot", "()D"); + method_glonassSatelliteAlmanacGetEccentricity = + env->GetMethodID(glonassSatelliteAlmanacClass, "getEccentricity", "()D"); + method_glonassSatelliteAlmanacGetFrequencyChannelNumber = + env->GetMethodID(glonassSatelliteAlmanacClass, "getFrequencyChannelNumber", "()I"); + method_glonassSatelliteAlmanacGetLambda = + env->GetMethodID(glonassSatelliteAlmanacClass, "getLambda", "()D"); + method_glonassSatelliteAlmanacGetOmega = + env->GetMethodID(glonassSatelliteAlmanacClass, "getOmega", "()D"); + method_glonassSatelliteAlmanacGetSlotNumber = + env->GetMethodID(glonassSatelliteAlmanacClass, "getSlotNumber", "()I"); + method_glonassSatelliteAlmanacGetHealthState = + env->GetMethodID(glonassSatelliteAlmanacClass, "getHealthState", "()I"); + method_glonassSatelliteAlmanacGetTLambda = + env->GetMethodID(glonassSatelliteAlmanacClass, "getTLambda", "()D"); + method_glonassSatelliteAlmanacGetTau = + env->GetMethodID(glonassSatelliteAlmanacClass, "getTau", "()D"); + method_glonassSatelliteAlmanacGetCalendarDayNumber = + env->GetMethodID(glonassSatelliteAlmanacClass, "getCalendarDayNumber", "()I"); + method_glonassSatelliteAlmanacGetIsGlonassM = + env->GetMethodID(glonassSatelliteAlmanacClass, "isGlonassM", "()Z"); + + // Get the methods of GlonassSatelliteEphemeris + jclass glonassSatelliteEphemerisClass = + env->FindClass("android/location/GlonassSatelliteEphemeris"); + method_glonassSatelliteEphemerisGetAgeInDays = + env->GetMethodID(glonassSatelliteEphemerisClass, "getAgeInDays", "()I"); + method_glonassSatelliteEphemerisGetFrameTimeSeconds = + env->GetMethodID(glonassSatelliteEphemerisClass, "getFrameTimeSeconds", "()D"); + method_glonassSatelliteEphemerisGetHealthState = + env->GetMethodID(glonassSatelliteEphemerisClass, "getHealthState", "()I"); + method_glonassSatelliteEphemerisGetSlotNumber = + env->GetMethodID(glonassSatelliteEphemerisClass, "getSlotNumber", "()I"); + method_glonassSatelliteEphemerisGetSatelliteClockModel = + env->GetMethodID(glonassSatelliteEphemerisClass, "getSatelliteClockModel", + "()Landroid/location/" + "GlonassSatelliteEphemeris$GlonassSatelliteClockModel;"); + method_glonassSatelliteEphemerisGetSatelliteOrbitModel = + env->GetMethodID(glonassSatelliteEphemerisClass, "getSatelliteOrbitModel", + "()Landroid/location/" + "GlonassSatelliteEphemeris$GlonassSatelliteOrbitModel;"); + method_glonassSatelliteEphemerisGetUpdateIntervalMinutes = + env->GetMethodID(glonassSatelliteEphemerisClass, "getUpdateIntervalMinutes", "()I"); + method_glonassSatelliteEphemerisGetIsGlonassM = + env->GetMethodID(glonassSatelliteEphemerisClass, "isGlonassM", "()Z"); + method_glonassSatelliteEphemerisGetIsUpdateIntervalOdd = + env->GetMethodID(glonassSatelliteEphemerisClass, "isUpdateIntervalOdd", "()Z"); + + // Get the methods of GlonassSatelliteOrbitModel + jclass glonassSatelliteOrbitModelClass = + env->FindClass("android/location/GlonassSatelliteEphemeris$GlonassSatelliteOrbitModel"); + method_glonassSatelliteOrbitModelGetX = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getX", "()D"); + method_glonassSatelliteOrbitModelGetXAccel = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getXAccel", "()D"); + method_glonassSatelliteOrbitModelGetXDot = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getXDot", "()D"); + method_glonassSatelliteOrbitModelGetY = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getY", "()D"); + method_glonassSatelliteOrbitModelGetYAccel = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getYAccel", "()D"); + method_glonassSatelliteOrbitModelGetYDot = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getYDot", "()D"); + method_glonassSatelliteOrbitModelGetZ = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getZ", "()D"); + method_glonassSatelliteOrbitModelGetZAccel = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getZAccel", "()D"); + method_glonassSatelliteOrbitModelGetZDot = + env->GetMethodID(glonassSatelliteOrbitModelClass, "getZDot", "()D"); + + // Get the methods of GlonassSatelliteClockModel + jclass glonassSatelliteClockModelClass = + env->FindClass("android/location/GlonassSatelliteEphemeris$GlonassSatelliteClockModel"); + method_glonassSatelliteClockModelGetClockBias = + env->GetMethodID(glonassSatelliteClockModelClass, "getClockBias", "()D"); + method_glonassSatelliteClockModelGetFrequencyBias = + env->GetMethodID(glonassSatelliteClockModelClass, "getFrequencyBias", "()D"); + method_glonassSatelliteClockModelGetFrequencyChannelNumber = + env->GetMethodID(glonassSatelliteClockModelClass, "getFrequencyChannelNumber", "()I"); + method_glonassSatelliteClockModelGetTimeOfClockSeconds = + env->GetMethodID(glonassSatelliteClockModelClass, "getTimeOfClockSeconds", "()J"); + + // Get the methods of QzssAssistance class. + jclass qzssAssistanceClass = env->FindClass("android/location/QzssAssistance"); + method_qzssAssistanceGetAlmanac = + env->GetMethodID(qzssAssistanceClass, "getAlmanac", "()Landroid/location/GnssAlmanac;"); + method_qzssAssistanceGetIonosphericModel = + env->GetMethodID(qzssAssistanceClass, "getIonosphericModel", + "()Landroid/location/KlobucharIonosphericModel;"); + method_qzssAssistanceGetUtcModel = + env->GetMethodID(qzssAssistanceClass, "getUtcModel", "()Landroid/location/UtcModel;"); + method_qzssAssistanceGetLeapSecondsModel = + env->GetMethodID(qzssAssistanceClass, "getLeapSecondsModel", + "()Landroid/location/LeapSecondsModel;"); + method_qzssAssistanceGetTimeModels = + env->GetMethodID(qzssAssistanceClass, "getTimeModels", "()Ljava/util/List;"); + method_qzssAssistanceGetSatelliteEphemeris = + env->GetMethodID(qzssAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;"); + method_qzssAssistanceGetSatelliteCorrections = + env->GetMethodID(qzssAssistanceClass, "getSatelliteCorrections", "()Ljava/util/List;"); + + // Get the methods of QzssSatelliteEphemeris class. + jclass qzssSatelliteEphemerisClass = env->FindClass("android/location/QzssSatelliteEphemeris"); + method_qzssSatelliteEphemerisGetSvid = + env->GetMethodID(qzssSatelliteEphemerisClass, "getSvid", "()I"); + method_qzssSatelliteEphemerisGetGpsL2Params = + env->GetMethodID(qzssSatelliteEphemerisClass, "getGpsL2Params", + "()Landroid/location/GpsSatelliteEphemeris$GpsL2Params;"); + method_qzssSatelliteEphemerisGetSatelliteEphemerisTime = + env->GetMethodID(qzssSatelliteEphemerisClass, "getSatelliteEphemerisTime", + "()Landroid/location/SatelliteEphemerisTime;"); + method_qzssSatelliteEphemerisGetSatelliteHealth = + env->GetMethodID(qzssSatelliteEphemerisClass, "getSatelliteHealth", + "()Landroid/location/GpsSatelliteEphemeris$GpsSatelliteHealth;"); + method_qzssSatelliteEphemerisGetSatelliteOrbitModel = + env->GetMethodID(qzssSatelliteEphemerisClass, "getSatelliteOrbitModel", + "()Landroid/location/KeplerianOrbitModel;"); +} + +GnssAssistanceInterface::GnssAssistanceInterface( + const sp<IGnssAssistanceInterface>& iGnssAssistance) + : mGnssAssistanceInterface(iGnssAssistance) { + assert(mGnssAssistanceInterface != nullptr); +} + +jboolean GnssAssistanceInterface::injectGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj) { + GnssAssistance gnssAssistance; + GnssAssistanceUtil::setGnssAssistance(env, gnssAssistanceObj, gnssAssistance); + auto status = mGnssAssistanceInterface->injectGnssAssistance(gnssAssistance); + return checkAidlStatus(status, "IGnssAssistanceInterface injectGnssAssistance() failed."); +} + +jboolean GnssAssistanceInterface::setCallback(const sp<IGnssAssistanceCallback>& callback) { + auto status = mGnssAssistanceInterface->setCallback(callback); + return checkAidlStatus(status, "IGnssAssistanceInterface setCallback() failed."); +} + +void GnssAssistanceUtil::setGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj, + GnssAssistance& gnssAssistance) { + jobject gpsAssistanceObj = + env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetGpsAssistance); + jobject glonassAssistanceObj = + env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetGlonassAssistance); + jobject qzssAssistanceObj = + env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetQzssAssistance); + jobject galileoAssistanceObj = + env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetGalileoAssistance); + jobject beidouAssistanceObj = + env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetBeidouAssistance); + GnssAssistanceUtil::setGpsAssistance(env, gpsAssistanceObj, gnssAssistance.gpsAssistance); + GnssAssistanceUtil::setGlonassAssistance(env, glonassAssistanceObj, + gnssAssistance.glonassAssistance); + GnssAssistanceUtil::setQzssAssistance(env, qzssAssistanceObj, gnssAssistance.qzssAssistance); + GnssAssistanceUtil::setGalileoAssistance(env, galileoAssistanceObj, + gnssAssistance.galileoAssistance); + GnssAssistanceUtil::setBeidouAssistance(env, beidouAssistanceObj, + gnssAssistance.beidouAssistance); + env->DeleteLocalRef(gpsAssistanceObj); + env->DeleteLocalRef(glonassAssistanceObj); + env->DeleteLocalRef(qzssAssistanceObj); + env->DeleteLocalRef(galileoAssistanceObj); + env->DeleteLocalRef(beidouAssistanceObj); +} + +void GnssAssistanceUtil::setQzssAssistance(JNIEnv* env, jobject qzssAssistanceObj, + QzssAssistance& qzssAssistance) { + jobject qzssAlmanacObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetAlmanac); + jobject qzssIonosphericModelObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetIonosphericModel); + jobject qzssUtcModelObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetUtcModel); + jobject qzssLeapSecondsModelObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetLeapSecondsModel); + jobject qzssTimeModelsObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetTimeModels); + jobject qzssSatelliteEphemerisObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetSatelliteEphemeris); + jobject qzssSatelliteCorrectionsObj = + env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetSatelliteCorrections); + setGnssAlmanac(env, qzssAlmanacObj, qzssAssistance.almanac); + setKlobucharIonosphericModel(env, qzssIonosphericModelObj, qzssAssistance.ionosphericModel); + setUtcModel(env, qzssUtcModelObj, qzssAssistance.utcModel); + setLeapSecondsModel(env, qzssLeapSecondsModelObj, qzssAssistance.leapSecondsModel); + setTimeModels(env, qzssTimeModelsObj, qzssAssistance.timeModels); + setGpsOrQzssSatelliteEphemeris<QzssSatelliteEphemeris>(env, qzssSatelliteEphemerisObj, + qzssAssistance.satelliteEphemeris); + setSatelliteCorrections(env, qzssSatelliteCorrectionsObj, qzssAssistance.satelliteCorrections); + env->DeleteLocalRef(qzssAlmanacObj); + env->DeleteLocalRef(qzssIonosphericModelObj); + env->DeleteLocalRef(qzssUtcModelObj); + env->DeleteLocalRef(qzssLeapSecondsModelObj); + env->DeleteLocalRef(qzssTimeModelsObj); + env->DeleteLocalRef(qzssSatelliteEphemerisObj); + env->DeleteLocalRef(qzssSatelliteCorrectionsObj); +} + +void GnssAssistanceUtil::setGlonassAssistance(JNIEnv* env, jobject glonassAssistanceObj, + GlonassAssistance& galileoAssistance) { + jobject glonassAlmanacObj = + env->CallObjectMethod(glonassAssistanceObj, method_glonassAssistanceGetAlmanac); + jobject utcModelObj = + env->CallObjectMethod(glonassAssistanceObj, method_glonassAssistanceGetUtcModel); + jobject timeModelsObj = + env->CallObjectMethod(glonassAssistanceObj, method_glonassAssistanceGetTimeModels); + jobject satelliteEphemerisObj = + env->CallObjectMethod(glonassAssistanceObj, + method_glonassAssistanceGetSatelliteEphemeris); + jobject satelliteCorrectionsObj = + env->CallObjectMethod(glonassAssistanceObj, + method_glonassAssistanceGetSatelliteCorrections); + setGlonassAlmanac(env, glonassAlmanacObj, galileoAssistance.almanac); + setUtcModel(env, utcModelObj, galileoAssistance.utcModel); + setTimeModels(env, timeModelsObj, galileoAssistance.timeModels); + setGlonassSatelliteEphemeris(env, satelliteEphemerisObj, galileoAssistance.satelliteEphemeris); + setSatelliteCorrections(env, satelliteCorrectionsObj, galileoAssistance.satelliteCorrections); + env->DeleteLocalRef(glonassAlmanacObj); + env->DeleteLocalRef(utcModelObj); + env->DeleteLocalRef(timeModelsObj); + env->DeleteLocalRef(satelliteEphemerisObj); + env->DeleteLocalRef(satelliteCorrectionsObj); +} + +void GnssAssistanceUtil::setGlonassAlmanac(JNIEnv* env, jobject glonassAlmanacObj, + GlonassAlmanac& glonassAlmanac) { + if (glonassAlmanacObj == nullptr) { + glonassAlmanac.issueDateMs = -1; + return; + } + jlong issueDateMillis = + env->CallLongMethod(glonassAlmanacObj, method_glonassAlmanacGetIssueDateMillis); + glonassAlmanac.issueDateMs = issueDateMillis; + jobject satelliteAlmanacsObj = + env->CallObjectMethod(glonassAlmanacObj, method_glonassAlmanacGetSatelliteAlmanacs); + if (satelliteAlmanacsObj == nullptr) return; + auto len = env->CallIntMethod(satelliteAlmanacsObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject glonassSatelliteAlmanacObj = + env->CallObjectMethod(satelliteAlmanacsObj, method_listGet, i); + if (glonassSatelliteAlmanacObj == nullptr) continue; + GlonassSatelliteAlmanac glonassSatelliteAlmanac; + jdouble deltaI = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetDeltaI); + glonassSatelliteAlmanac.deltaI = deltaI; + jdouble deltaT = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetDeltaT); + glonassSatelliteAlmanac.deltaT = deltaT; + jdouble deltaTDot = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetDeltaTDot); + glonassSatelliteAlmanac.deltaTDot = deltaTDot; + jdouble eccentricity = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetEccentricity); + glonassSatelliteAlmanac.eccentricity = eccentricity; + jint frequencyChannelNumber = + env->CallIntMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetFrequencyChannelNumber); + glonassSatelliteAlmanac.frequencyChannelNumber = + static_cast<int32_t>(frequencyChannelNumber); + jdouble lambda = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetLambda); + glonassSatelliteAlmanac.lambda = lambda; + jdouble omega = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetOmega); + glonassSatelliteAlmanac.omega = omega; + jint slotNumber = env->CallIntMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetSlotNumber); + glonassSatelliteAlmanac.slotNumber = static_cast<int32_t>(slotNumber); + jint healthState = env->CallIntMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetHealthState); + glonassSatelliteAlmanac.svHealth = static_cast<int32_t>(healthState); + jdouble tLambda = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetTLambda); + glonassSatelliteAlmanac.tLambda = tLambda; + jdouble tau = env->CallDoubleMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetTau); + glonassSatelliteAlmanac.tau = tau; + jboolean isGlonassM = env->CallBooleanMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetIsGlonassM); + glonassSatelliteAlmanac.isGlonassM = isGlonassM; + jint calendarDayNumber = + env->CallIntMethod(glonassSatelliteAlmanacObj, + method_glonassSatelliteAlmanacGetCalendarDayNumber); + glonassSatelliteAlmanac.calendarDayNumber = static_cast<int32_t>(calendarDayNumber); + glonassAlmanac.satelliteAlmanacs.push_back(glonassSatelliteAlmanac); + env->DeleteLocalRef(glonassSatelliteAlmanacObj); + } + env->DeleteLocalRef(satelliteAlmanacsObj); +} + +void GnssAssistanceUtil::setGlonassSatelliteEphemeris( + JNIEnv* env, jobject glonassSatelliteEphemerisListObj, + std::vector<GlonassSatelliteEphemeris>& glonassSatelliteEphemerisList) { + if (glonassSatelliteEphemerisListObj == nullptr) return; + auto len = env->CallIntMethod(glonassSatelliteEphemerisListObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject glonassSatelliteEphemerisObj = + env->CallObjectMethod(glonassSatelliteEphemerisListObj, method_listGet, i); + if (glonassSatelliteEphemerisObj == nullptr) continue; + GlonassSatelliteEphemeris glonassSatelliteEphemeris; + jdouble ageInDays = env->CallDoubleMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetAgeInDays); + glonassSatelliteEphemeris.ageInDays = ageInDays; + + // Set the GlonassSatelliteClockModel. + jobject glonassSatelliteClockModelObj = + env->CallObjectMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetSatelliteClockModel); + GlonassSatelliteClockModel glonassSatelliteClockModel; + jdouble clockBias = env->CallDoubleMethod(glonassSatelliteClockModelObj, + method_glonassSatelliteClockModelGetClockBias); + glonassSatelliteClockModel.clockBias = clockBias; + jdouble frequencyBias = + env->CallDoubleMethod(glonassSatelliteClockModelObj, + method_glonassSatelliteClockModelGetFrequencyBias); + glonassSatelliteClockModel.frequencyBias = frequencyBias; + jint frequencyChannelNumber = + env->CallIntMethod(glonassSatelliteClockModelObj, + method_glonassSatelliteClockModelGetFrequencyChannelNumber); + glonassSatelliteClockModel.frequencyChannelNumber = + static_cast<int32_t>(frequencyChannelNumber); + jdouble timeOfClockSeconds = + env->CallDoubleMethod(glonassSatelliteClockModelObj, + method_glonassSatelliteClockModelGetTimeOfClockSeconds); + glonassSatelliteClockModel.timeOfClockSeconds = timeOfClockSeconds; + glonassSatelliteEphemeris.satelliteClockModel = glonassSatelliteClockModel; + env->DeleteLocalRef(glonassSatelliteClockModelObj); + + // Set the GlonassSatelliteOrbitModel. + jobject glonassSatelliteOrbitModelObj = + env->CallObjectMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetSatelliteOrbitModel); + GlonassSatelliteOrbitModel glonassSatelliteOrbitModel; + jdouble x = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetX); + glonassSatelliteOrbitModel.x = x; + jdouble y = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetY); + glonassSatelliteOrbitModel.y = y; + jdouble z = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetZ); + glonassSatelliteOrbitModel.z = z; + jdouble xAccel = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetXAccel); + glonassSatelliteOrbitModel.xAccel = xAccel; + jdouble yAccel = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetYAccel); + glonassSatelliteOrbitModel.yAccel = yAccel; + jdouble zAccel = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetZAccel); + glonassSatelliteOrbitModel.zAccel = zAccel; + jdouble xDot = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetXDot); + glonassSatelliteOrbitModel.xDot = xDot; + jdouble yDot = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetYDot); + glonassSatelliteOrbitModel.yDot = yDot; + jdouble zDot = env->CallDoubleMethod(glonassSatelliteOrbitModelObj, + method_glonassSatelliteOrbitModelGetZDot); + glonassSatelliteOrbitModel.zDot = zDot; + glonassSatelliteEphemeris.satelliteOrbitModel = glonassSatelliteOrbitModel; + env->DeleteLocalRef(glonassSatelliteOrbitModelObj); + + jint healthState = env->CallIntMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetHealthState); + glonassSatelliteEphemeris.svHealth = static_cast<int32_t>(healthState); + jint slotNumber = env->CallIntMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetSlotNumber); + glonassSatelliteEphemeris.slotNumber = static_cast<int32_t>(slotNumber); + jdouble frameTimeSeconds = + env->CallDoubleMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetFrameTimeSeconds); + glonassSatelliteEphemeris.frameTimeSeconds = frameTimeSeconds; + jint updateIntervalMinutes = + env->CallIntMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetUpdateIntervalMinutes); + glonassSatelliteEphemeris.updateIntervalMinutes = + static_cast<int32_t>(updateIntervalMinutes); + jboolean isGlonassM = env->CallBooleanMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetIsGlonassM); + glonassSatelliteEphemeris.isGlonassM = isGlonassM; + jboolean isUpdateIntervalOdd = + env->CallBooleanMethod(glonassSatelliteEphemerisObj, + method_glonassSatelliteEphemerisGetIsUpdateIntervalOdd); + glonassSatelliteEphemeris.isOddUpdateInterval = isUpdateIntervalOdd; + glonassSatelliteEphemerisList.push_back(glonassSatelliteEphemeris); + env->DeleteLocalRef(glonassSatelliteEphemerisObj); + } +} + +void GnssAssistanceUtil::setGalileoAssistance(JNIEnv* env, jobject galileoAssistanceObj, + GalileoAssistance& galileoAssistance) { + jobject galileoAlmanacObj = + env->CallObjectMethod(galileoAssistanceObj, method_galileoAssistanceGetAlmanac); + jobject ionosphericModelObj = + env->CallObjectMethod(galileoAssistanceObj, + method_galileoAssistanceGetIonosphericModel); + jobject utcModelObj = + env->CallObjectMethod(galileoAssistanceObj, method_galileoAssistanceGetUtcModel); + jobject leapSecondsModelObj = + env->CallObjectMethod(galileoAssistanceObj, + method_galileoAssistanceGetLeapSecondsModel); + jobject timeModelsObj = + env->CallObjectMethod(galileoAssistanceObj, method_galileoAssistanceGetTimeModels); + jobject satelliteEphemerisObj = + env->CallObjectMethod(galileoAssistanceObj, + method_galileoAssistanceGetSatelliteEphemeris); + jobject realTimeIntegrityModelsObj = + env->CallObjectMethod(galileoAssistanceObj, + method_galileoAssistanceGetRealTimeIntegrityModels); + jobject satelliteCorrectionsObj = + env->CallObjectMethod(galileoAssistanceObj, + method_galileoAssistanceGetSatelliteCorrections); + setGnssAlmanac(env, galileoAlmanacObj, galileoAssistance.almanac); + setGaliloKlobucharIonosphericModel(env, ionosphericModelObj, + galileoAssistance.ionosphericModel); + setUtcModel(env, utcModelObj, galileoAssistance.utcModel); + setLeapSecondsModel(env, leapSecondsModelObj, galileoAssistance.leapSecondsModel); + setTimeModels(env, timeModelsObj, galileoAssistance.timeModels); + setGalileoSatelliteEphemeris(env, satelliteEphemerisObj, galileoAssistance.satelliteEphemeris); + setRealTimeIntegrityModels(env, realTimeIntegrityModelsObj, + galileoAssistance.realTimeIntegrityModels); + setSatelliteCorrections(env, satelliteCorrectionsObj, galileoAssistance.satelliteCorrections); + env->DeleteLocalRef(galileoAlmanacObj); + env->DeleteLocalRef(ionosphericModelObj); + env->DeleteLocalRef(utcModelObj); + env->DeleteLocalRef(leapSecondsModelObj); + env->DeleteLocalRef(timeModelsObj); + env->DeleteLocalRef(satelliteEphemerisObj); + env->DeleteLocalRef(realTimeIntegrityModelsObj); + env->DeleteLocalRef(satelliteCorrectionsObj); +} + +void GnssAssistanceUtil::setGaliloKlobucharIonosphericModel( + JNIEnv* env, jobject galileoIonosphericModelObj, + GalileoIonosphericModel& ionosphericModel) { + if (galileoIonosphericModelObj == nullptr) return; + jdouble ai0 = + env->CallDoubleMethod(galileoIonosphericModelObj, method_galileoIonosphericModelGetAi0); + ionosphericModel.ai0 = ai0; + jdouble ai1 = + env->CallDoubleMethod(galileoIonosphericModelObj, method_galileoIonosphericModelGetAi1); + ionosphericModel.ai1 = ai1; + jdouble ai2 = + env->CallDoubleMethod(galileoIonosphericModelObj, method_galileoIonosphericModelGetAi2); + ionosphericModel.ai2 = ai2; +} + +void GnssAssistanceUtil::setGalileoSatelliteEphemeris( + JNIEnv* env, jobject galileoSatelliteEphemerisListObj, + std::vector<GalileoSatelliteEphemeris>& galileoSatelliteEphemerisList) { + if (galileoSatelliteEphemerisListObj == nullptr) return; + auto len = env->CallIntMethod(galileoSatelliteEphemerisListObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject galileoSatelliteEphemerisObj = + env->CallObjectMethod(galileoSatelliteEphemerisListObj, method_listGet, i); + GalileoSatelliteEphemeris galileoSatelliteEphemeris; + GalileoSvHealth galileoSvHealth; + // Set the svid of the satellite. + jint svid = env->CallLongMethod(galileoSatelliteEphemerisObj, + method_galileoSatelliteEphemerisGetSvid); + galileoSatelliteEphemeris.svid = svid; + + // Set the satellite clock models. + jobject galileoSatelliteClockModelListObj = + env->CallObjectMethod(galileoSatelliteEphemerisObj, + method_galileoSatelliteEphemerisGetSatelliteClockModels); + auto size = env->CallIntMethod(galileoSatelliteClockModelListObj, method_listSize); + for (uint16_t j = 0; j < size; ++j) { + jobject galileoSatelliteClockModelObj = + env->CallObjectMethod(galileoSatelliteClockModelListObj, method_listGet, j); + if (galileoSatelliteClockModelObj == nullptr) continue; + GalileoSatelliteClockModel galileoSatelliteClockModel; + jdouble af0 = env->CallDoubleMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetAf0); + galileoSatelliteClockModel.af0 = af0; + jdouble af1 = env->CallDoubleMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetAf1); + galileoSatelliteClockModel.af1 = af1; + jdouble af2 = env->CallDoubleMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetAf2); + galileoSatelliteClockModel.af2 = af2; + jdouble bgdSeconds = + env->CallDoubleMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetBgdSeconds); + galileoSatelliteClockModel.bgdSeconds = bgdSeconds; + jint satelliteClockType = + env->CallIntMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetSatelliteClockType); + galileoSatelliteClockModel.satelliteClockType = + static_cast<GalileoSatelliteClockModel::SatelliteClockType>(satelliteClockType); + jdouble sisaMeters = + env->CallDoubleMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetSisaMeters); + galileoSatelliteClockModel.sisaMeters = sisaMeters; + jdouble timeOfClockSeconds = + env->CallDoubleMethod(galileoSatelliteClockModelObj, + method_galileoSatelliteClockModelGetTimeOfClockSeconds); + galileoSatelliteClockModel.timeOfClockSeconds = timeOfClockSeconds; + galileoSatelliteEphemeris.satelliteClockModel.push_back(galileoSatelliteClockModel); + env->DeleteLocalRef(galileoSatelliteClockModelObj); + } + env->DeleteLocalRef(galileoSatelliteClockModelListObj); + + // Set the satelliteOrbitModel of the satellite. + jobject satelliteOrbitModelObj = + env->CallObjectMethod(galileoSatelliteEphemerisObj, + method_galileoSatelliteEphemerisGetSatelliteOrbitModel); + GnssAssistanceUtil::setKeplerianOrbitModel(env, satelliteOrbitModelObj, + galileoSatelliteEphemeris.satelliteOrbitModel); + env->DeleteLocalRef(satelliteOrbitModelObj); + + // Set the satellite health of the satellite clock model. + jobject galileoSvHealthObj = + env->CallObjectMethod(galileoSatelliteEphemerisObj, + method_galileoSatelliteEphemerisGetSatelliteHealth); + jint dataValidityStatusE1b = + env->CallIntMethod(galileoSvHealthObj, + method_galileoSvHealthGetDataValidityStatusE1b); + galileoSvHealth.dataValidityStatusE1b = + static_cast<GalileoSvHealth::GalileoHealthDataVaidityType>(dataValidityStatusE1b); + jint dataValidityStatusE5a = + env->CallIntMethod(galileoSvHealthObj, + method_galileoSvHealthGetDataValidityStatusE5a); + galileoSvHealth.dataValidityStatusE5a = + static_cast<GalileoSvHealth::GalileoHealthDataVaidityType>(dataValidityStatusE5a); + jint dataValidityStatusE5b = + env->CallIntMethod(galileoSvHealthObj, + method_galileoSvHealthGetDataValidityStatusE5b); + galileoSvHealth.dataValidityStatusE5b = + static_cast<GalileoSvHealth::GalileoHealthDataVaidityType>(dataValidityStatusE5b); + jint signalHealthStatusE1b = + env->CallIntMethod(galileoSvHealthObj, + method_galileoSvHealthGetSignalHealthStatusE1b); + galileoSvHealth.signalHealthStatusE1b = + static_cast<GalileoSvHealth::GalileoHealthStatusType>(signalHealthStatusE1b); + jint signalHealthStatusE5a = + env->CallIntMethod(galileoSvHealthObj, + method_galileoSvHealthGetSignalHealthStatusE5a); + galileoSvHealth.signalHealthStatusE5a = + static_cast<GalileoSvHealth::GalileoHealthStatusType>(signalHealthStatusE5a); + jint signalHealthStatusE5b = + env->CallIntMethod(galileoSvHealthObj, + method_galileoSvHealthGetSignalHealthStatusE5b); + galileoSvHealth.signalHealthStatusE5b = + static_cast<GalileoSvHealth::GalileoHealthStatusType>(signalHealthStatusE5b); + galileoSatelliteEphemeris.svHealth = galileoSvHealth; + env->DeleteLocalRef(galileoSvHealthObj); + + // Set the satelliteEphemerisTime of the satellite. + jobject satelliteEphemerisTimeObj = + env->CallObjectMethod(galileoSatelliteEphemerisObj, + method_galileoSatelliteEphemerisGetSatelliteEphemerisTime); + GnssAssistanceUtil::setSatelliteEphemerisTime(env, satelliteEphemerisTimeObj, + galileoSatelliteEphemeris + .satelliteEphemerisTime); + env->DeleteLocalRef(satelliteEphemerisTimeObj); + + galileoSatelliteEphemerisList.push_back(galileoSatelliteEphemeris); + env->DeleteLocalRef(galileoSatelliteEphemerisObj); + } +} + +void GnssAssistanceUtil::setBeidouAssistance(JNIEnv* env, jobject beidouAssistanceObj, + BeidouAssistance& beidouAssistance) { + jobject beidouAlmanacObj = + env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetAlmanac); + jobject ionosphericModelObj = + env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetIonosphericModel); + jobject utcModelObj = + env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetUtcModel); + jobject leapSecondsModelObj = + env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetLeapSecondsModel); + jobject timeModelsObj = + env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetTimeModels); + jobject satelliteEphemerisObj = + env->CallObjectMethod(beidouAssistanceObj, + method_beidouAssistanceGetSatelliteEphemeris); + jobject realTimeIntegrityModelsObj = + env->CallObjectMethod(beidouAssistanceObj, + method_beidouAssistanceGetRealTimeIntegrityModels); + jobject satelliteCorrectionsObj = + env->CallObjectMethod(beidouAssistanceObj, + method_beidouAssistanceGetSatelliteCorrections); + setGnssAlmanac(env, beidouAlmanacObj, beidouAssistance.almanac); + setKlobucharIonosphericModel(env, ionosphericModelObj, beidouAssistance.ionosphericModel); + setUtcModel(env, utcModelObj, beidouAssistance.utcModel); + setLeapSecondsModel(env, leapSecondsModelObj, beidouAssistance.leapSecondsModel); + setTimeModels(env, timeModelsObj, beidouAssistance.timeModels); + setBeidouSatelliteEphemeris(env, satelliteEphemerisObj, beidouAssistance.satelliteEphemeris); + setRealTimeIntegrityModels(env, realTimeIntegrityModelsObj, + beidouAssistance.realTimeIntegrityModels); + setSatelliteCorrections(env, satelliteCorrectionsObj, beidouAssistance.satelliteCorrections); + env->DeleteLocalRef(beidouAlmanacObj); + env->DeleteLocalRef(ionosphericModelObj); + env->DeleteLocalRef(utcModelObj); + env->DeleteLocalRef(leapSecondsModelObj); + env->DeleteLocalRef(timeModelsObj); + env->DeleteLocalRef(satelliteEphemerisObj); + env->DeleteLocalRef(realTimeIntegrityModelsObj); + env->DeleteLocalRef(satelliteCorrectionsObj); +} + +void GnssAssistanceUtil::setBeidouSatelliteEphemeris( + JNIEnv* env, jobject beidouSatelliteEphemerisListObj, + std::vector<BeidouSatelliteEphemeris>& beidouSatelliteEphemerisList) { + if (beidouSatelliteEphemerisListObj == nullptr) return; + auto len = env->CallIntMethod(beidouSatelliteEphemerisListObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject beidouSatelliteEphemerisObj = + env->CallObjectMethod(beidouSatelliteEphemerisListObj, method_listGet, i); + if (beidouSatelliteEphemerisObj == nullptr) continue; + BeidouSatelliteEphemeris beidouSatelliteEphemeris; + + // Set the svid of the satellite. + jint svid = env->CallIntMethod(beidouSatelliteEphemerisObj, + method_beidouSatelliteEphemerisGetSvid); + beidouSatelliteEphemeris.svid = static_cast<int32_t>(svid); + + // Set the satelliteClockModel of the satellite. + jobject satelliteClockModelObj = + env->CallObjectMethod(beidouSatelliteEphemerisObj, + method_beidouSatelliteEphemerisGetSatelliteClockModel); + jdouble af0 = env->CallDoubleMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetAf0); + jdouble af1 = env->CallDoubleMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetAf1); + jdouble af2 = env->CallDoubleMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetAf2); + jdouble tgd1 = env->CallDoubleMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetTgd1); + jdouble tgd2 = env->CallDoubleMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetTgd2); + jdouble aodc = env->CallDoubleMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetAodc); + jlong timeOfClockSeconds = + env->CallLongMethod(satelliteClockModelObj, + method_beidouSatelliteClockModelGetTimeOfClockSeconds); + beidouSatelliteEphemeris.satelliteClockModel.af0 = af0; + beidouSatelliteEphemeris.satelliteClockModel.af1 = af1; + beidouSatelliteEphemeris.satelliteClockModel.af2 = af2; + beidouSatelliteEphemeris.satelliteClockModel.tgd1 = tgd1; + beidouSatelliteEphemeris.satelliteClockModel.tgd2 = tgd2; + beidouSatelliteEphemeris.satelliteClockModel.aodc = aodc; + beidouSatelliteEphemeris.satelliteClockModel.timeOfClockSeconds = timeOfClockSeconds; + env->DeleteLocalRef(satelliteClockModelObj); + + // Set the satelliteOrbitModel of the satellite. + jobject satelliteOrbitModelObj = + env->CallObjectMethod(beidouSatelliteEphemerisObj, + method_beidouSatelliteEphemerisGetSatelliteOrbitModel); + GnssAssistanceUtil::setKeplerianOrbitModel(env, satelliteOrbitModelObj, + beidouSatelliteEphemeris.satelliteOrbitModel); + env->DeleteLocalRef(satelliteOrbitModelObj); + + // Set the satelliteHealth of the satellite. + jobject satelliteHealthObj = + env->CallObjectMethod(beidouSatelliteEphemerisObj, + method_beidouSatelliteEphemerisGetSatelliteHealth); + jint satH1 = env->CallIntMethod(satelliteHealthObj, method_beidouSatelliteHealthGetSatH1); + jint svAccur = + env->CallIntMethod(satelliteHealthObj, method_beidouSatelliteHealthGetSvAccur); + beidouSatelliteEphemeris.satelliteHealth.satH1 = static_cast<int32_t>(satH1); + beidouSatelliteEphemeris.satelliteHealth.svAccur = static_cast<int32_t>(svAccur); + env->DeleteLocalRef(satelliteHealthObj); + + // Set the satelliteEphemerisTime of the satellite. + jobject satelliteEphemerisTimeObj = + env->CallObjectMethod(beidouSatelliteEphemerisObj, + method_beidouSatelliteEphemerisGetSatelliteEphemerisTime); + jint iode = env->CallIntMethod(satelliteEphemerisTimeObj, + method_beidouSatelliteEphemerisTimeGetIode); + jint beidouWeekNumber = + env->CallIntMethod(satelliteEphemerisTimeObj, + method_beidouSatelliteEphemerisTimeGetBeidouWeekNumber); + jint toeSeconds = env->CallDoubleMethod(satelliteEphemerisTimeObj, + method_beidouSatelliteEphemerisTimeGetToeSeconds); + beidouSatelliteEphemeris.satelliteEphemerisTime.aode = static_cast<int32_t>(iode); + beidouSatelliteEphemeris.satelliteEphemerisTime.weekNumber = + static_cast<int32_t>(beidouWeekNumber); + beidouSatelliteEphemeris.satelliteEphemerisTime.toeSeconds = + static_cast<int32_t>(toeSeconds); + env->DeleteLocalRef(satelliteEphemerisTimeObj); + + beidouSatelliteEphemerisList.push_back(beidouSatelliteEphemeris); + env->DeleteLocalRef(beidouSatelliteEphemerisObj); + } +} + +void GnssAssistanceUtil::setGpsAssistance(JNIEnv* env, jobject gpsAssistanceObj, + GpsAssistance& gpsAssistance) { + jobject gnssAlmanacObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetAlmanac); + jobject ionosphericModelObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetIonosphericModel); + jobject utcModelObj = env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetUtcModel); + jobject leapSecondsModelObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetLeapSecondsModel); + jobject timeModelsObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetTimeModels); + jobject satelliteEphemerisObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetSatelliteEphemeris); + jobject realTimeIntegrityModelsObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetRealTimeIntegrityModels); + jobject satelliteCorrectionsObj = + env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetSatelliteCorrections); + + setGnssAlmanac(env, gnssAlmanacObj, gpsAssistance.almanac); + setKlobucharIonosphericModel(env, ionosphericModelObj, gpsAssistance.ionosphericModel); + setUtcModel(env, utcModelObj, gpsAssistance.utcModel); + setLeapSecondsModel(env, leapSecondsModelObj, gpsAssistance.leapSecondsModel); + setTimeModels(env, timeModelsObj, gpsAssistance.timeModels); + setGpsOrQzssSatelliteEphemeris<GpsSatelliteEphemeris>(env, satelliteEphemerisObj, + gpsAssistance.satelliteEphemeris); + setRealTimeIntegrityModels(env, realTimeIntegrityModelsObj, + gpsAssistance.realTimeIntegrityModels); + setSatelliteCorrections(env, satelliteCorrectionsObj, gpsAssistance.satelliteCorrections); + env->DeleteLocalRef(gnssAlmanacObj); + env->DeleteLocalRef(ionosphericModelObj); + env->DeleteLocalRef(utcModelObj); + env->DeleteLocalRef(leapSecondsModelObj); + env->DeleteLocalRef(timeModelsObj); + env->DeleteLocalRef(satelliteEphemerisObj); + env->DeleteLocalRef(realTimeIntegrityModelsObj); + env->DeleteLocalRef(satelliteCorrectionsObj); +} + +/** Set the GPS/QZSS satellite ephemeris list. */ +template <class T> +void GnssAssistanceUtil::setGpsOrQzssSatelliteEphemeris(JNIEnv* env, + jobject satelliteEphemerisListObj, + std::vector<T>& satelliteEphemerisList) { + if (satelliteEphemerisListObj == nullptr) return; + auto len = env->CallIntMethod(satelliteEphemerisListObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject satelliteEphemerisObj = + env->CallObjectMethod(satelliteEphemerisListObj, method_listGet, i); + if (satelliteEphemerisObj == nullptr) continue; + T satelliteEphemeris; + // Set the svid of the satellite. + jint svid = env->CallIntMethod(satelliteEphemerisObj, method_gpsSatelliteEphemerisGetSvid); + satelliteEphemeris.svid = static_cast<int32_t>(svid); + + // Set the gpsL2Params of the satellite. + jobject gpsL2ParamsObj = env->CallObjectMethod(satelliteEphemerisObj, + method_gpsSatelliteEphemerisGetGpsL2Params); + jint l2Code = env->CallIntMethod(gpsL2ParamsObj, method_gpsL2ParamsGetL2Code); + jint l2Flag = env->CallIntMethod(gpsL2ParamsObj, method_gpsL2ParamsGetL2Flag); + satelliteEphemeris.gpsL2Params.l2Code = static_cast<int32_t>(l2Code); + satelliteEphemeris.gpsL2Params.l2Flag = static_cast<int32_t>(l2Flag); + env->DeleteLocalRef(gpsL2ParamsObj); + + // Set the satelliteClockModel of the satellite. + jobject satelliteClockModelObj = + env->CallObjectMethod(satelliteEphemerisObj, + method_gpsSatelliteEphemerisGetSatelliteClockModel); + jdouble af0 = + env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetAf0); + jdouble af1 = + env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetAf1); + jdouble af2 = + env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetAf2); + jdouble tgd = + env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetTgd); + jint iodc = + env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetIodc); + jlong timeOfClockSeconds = + env->CallLongMethod(satelliteClockModelObj, + method_gpsSatelliteClockModelGetTimeOfClockSeconds); + satelliteEphemeris.satelliteClockModel.af0 = af0; + satelliteEphemeris.satelliteClockModel.af1 = af1; + satelliteEphemeris.satelliteClockModel.af2 = af2; + satelliteEphemeris.satelliteClockModel.tgd = tgd; + satelliteEphemeris.satelliteClockModel.iodc = static_cast<int32_t>(iodc); + satelliteEphemeris.satelliteClockModel.timeOfClockSeconds = timeOfClockSeconds; + env->DeleteLocalRef(satelliteClockModelObj); + + // Set the satelliteOrbitModel of the satellite. + jobject satelliteOrbitModelObj = + env->CallObjectMethod(satelliteEphemerisObj, + method_gpsSatelliteEphemerisGetSatelliteOrbitModel); + GnssAssistanceUtil::setKeplerianOrbitModel(env, satelliteOrbitModelObj, + satelliteEphemeris.satelliteOrbitModel); + env->DeleteLocalRef(satelliteOrbitModelObj); + + // Set the satelliteHealth of the satellite. + jobject satelliteHealthObj = + env->CallObjectMethod(satelliteEphemerisObj, + method_gpsSatelliteEphemerisGetSatelliteHealth); + jint svHealth = + env->CallIntMethod(satelliteHealthObj, method_gpsSatelliteHealthGetSvHealth); + jdouble svAccur = + env->CallDoubleMethod(satelliteHealthObj, method_gpsSatelliteHealthGetSvAccur); + jdouble fitInt = env->CallIntMethod(satelliteHealthObj, method_gpsSatelliteHealthGetFitInt); + satelliteEphemeris.satelliteHealth.svHealth = static_cast<int32_t>(svHealth); + satelliteEphemeris.satelliteHealth.svAccur = svAccur; + satelliteEphemeris.satelliteHealth.fitInt = fitInt; + env->DeleteLocalRef(satelliteHealthObj); + + // Set the satelliteEphemerisTime of the satellite. + jobject satelliteEphemerisTimeObj = + env->CallObjectMethod(satelliteEphemerisObj, + method_gpsSatelliteEphemerisGetSatelliteEphemerisTime); + GnssAssistanceUtil::setSatelliteEphemerisTime(env, satelliteEphemerisTimeObj, + satelliteEphemeris.satelliteEphemerisTime); + env->DeleteLocalRef(satelliteEphemerisTimeObj); + + satelliteEphemerisList.push_back(satelliteEphemeris); + env->DeleteLocalRef(satelliteEphemerisObj); + } +} + +void GnssAssistanceUtil::setSatelliteCorrections( + JNIEnv* env, jobject satelliteCorrectionsObj, + std::vector<GnssSatelliteCorrections>& gnssSatelliteCorrectionsList) { + if (satelliteCorrectionsObj == nullptr) return; + auto len = env->CallIntMethod(satelliteCorrectionsObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + GnssSatelliteCorrections gnssSatelliteCorrections; + jobject satelliteCorrectionObj = + env->CallObjectMethod(satelliteCorrectionsObj, method_listGet, i); + if (satelliteCorrectionObj == nullptr) continue; + jint svid = env->CallIntMethod(satelliteCorrectionObj, method_satelliteCorrectionGetSvid); + gnssSatelliteCorrections.svid = svid; + jobject ionosphericCorrectionsObj = + env->CallObjectMethod(satelliteCorrectionObj, + method_satelliteCorrectionGetIonosphericCorrections); + env->DeleteLocalRef(satelliteCorrectionObj); + auto size = env->CallIntMethod(ionosphericCorrectionsObj, method_listSize); + for (uint16_t j = 0; j < size; ++j) { + jobject ionosphericCorrectionObj = + env->CallObjectMethod(ionosphericCorrectionsObj, method_listGet, j); + if (ionosphericCorrectionObj == nullptr) continue; + IonosphericCorrection ionosphericCorrection; + jlong carrierFrequencyHz = + env->CallLongMethod(ionosphericCorrectionObj, + method_ionosphericCorrectionGetCarrierFrequencyHz); + ionosphericCorrection.carrierFrequencyHz = carrierFrequencyHz; + + jobject gnssCorrectionComponentObj = + env->CallObjectMethod(ionosphericCorrectionObj, + method_ionosphericCorrectionGetIonosphericCorrection); + env->DeleteLocalRef(ionosphericCorrectionObj); + + jstring sourceKey = static_cast<jstring>( + env->CallObjectMethod(gnssCorrectionComponentObj, + method_gnssCorrectionComponentGetSourceKey)); + ScopedJniString jniSourceKey{env, sourceKey}; + ionosphericCorrection.ionosphericCorrectionComponent.sourceKey = + android::String16(jniSourceKey.c_str()); + + jobject pseudorangeCorrectionObj = + env->CallObjectMethod(gnssCorrectionComponentObj, + method_gnssCorrectionComponentGetPseudorangeCorrection); + jdouble correctionMeters = + env->CallDoubleMethod(pseudorangeCorrectionObj, + method_pseudorangeCorrectionGetCorrectionMeters); + jdouble correctionUncertaintyMeters = env->CallDoubleMethod( + pseudorangeCorrectionObj, + method_pseudorangeCorrectionGetCorrectionUncertaintyMeters); + jdouble correctionRateMetersPerSecond = env->CallDoubleMethod( + pseudorangeCorrectionObj, + method_pseudorangeCorrectionGetCorrectionRateMetersPerSecond); + ionosphericCorrection.ionosphericCorrectionComponent.pseudorangeCorrection + .correctionMeters = correctionMeters; + ionosphericCorrection.ionosphericCorrectionComponent.pseudorangeCorrection + .correctionUncertaintyMeters = correctionUncertaintyMeters; + ionosphericCorrection.ionosphericCorrectionComponent.pseudorangeCorrection + .correctionRateMetersPerSecond = correctionRateMetersPerSecond; + env->DeleteLocalRef(pseudorangeCorrectionObj); + + jobject gnssIntervalObj = + env->CallObjectMethod(gnssCorrectionComponentObj, + method_gnssCorrectionComponentGetValidityInterval); + jdouble startMillisSinceGpsEpoch = + env->CallDoubleMethod(gnssIntervalObj, + method_gnssIntervalGetStartMillisSinceGpsEpoch); + jdouble endMillisSinceGpsEpoch = + env->CallDoubleMethod(gnssIntervalObj, + method_gnssIntervalGetEndMillisSinceGpsEpoch); + ionosphericCorrection.ionosphericCorrectionComponent.validityInterval + .startMillisSinceGpsEpoch = startMillisSinceGpsEpoch; + ionosphericCorrection.ionosphericCorrectionComponent.validityInterval + .endMillisSinceGpsEpoch = endMillisSinceGpsEpoch; + env->DeleteLocalRef(gnssIntervalObj); + + env->DeleteLocalRef(gnssCorrectionComponentObj); + gnssSatelliteCorrections.ionosphericCorrections.push_back(ionosphericCorrection); + } + gnssSatelliteCorrectionsList.push_back(gnssSatelliteCorrections); + env->DeleteLocalRef(ionosphericCorrectionsObj); + } +} + +void GnssAssistanceUtil::setRealTimeIntegrityModels( + JNIEnv* env, jobject realTimeIntegrityModelsObj, + std::vector<RealTimeIntegrityModel>& realTimeIntegrityModels) { + if (realTimeIntegrityModelsObj == nullptr) return; + auto len = env->CallIntMethod(realTimeIntegrityModelsObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject realTimeIntegrityModelObj = + env->CallObjectMethod(realTimeIntegrityModelsObj, method_listGet, i); + if (realTimeIntegrityModelObj == nullptr) continue; + RealTimeIntegrityModel realTimeIntegrityModel; + jint badSvid = env->CallIntMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetBadSvid); + jobject badSignalTypesObj = + env->CallObjectMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetBadSignalTypes); + auto badSignalTypesSize = env->CallIntMethod(badSignalTypesObj, method_listSize); + for (uint16_t j = 0; j < badSignalTypesSize; ++j) { + GnssSignalType badSignalType; + jobject badSignalTypeObj = env->CallObjectMethod(badSignalTypesObj, method_listGet, j); + if (badSignalTypeObj != nullptr) { + setGnssSignalType(env, badSignalTypeObj, badSignalType); + realTimeIntegrityModel.badSignalTypes.push_back(badSignalType); + env->DeleteLocalRef(badSignalTypeObj); + } + } + + jlong startDateSeconds = + env->CallLongMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetStartDateSeconds); + jlong endDateSeconds = env->CallLongMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetEndDateSeconds); + jlong publishDateSeconds = + env->CallLongMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetPublishDateSeconds); + jstring advisoryNumber = static_cast<jstring>( + env->CallObjectMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetAdvisoryNumber)); + ScopedJniString jniAdvisoryNumber{env, advisoryNumber}; + jstring advisoryType = static_cast<jstring>( + env->CallObjectMethod(realTimeIntegrityModelObj, + method_realTimeIntegrityModelGetAdvisoryType)); + ScopedJniString jniAdvisoryType{env, advisoryType}; + + realTimeIntegrityModel.badSvid = badSvid; + realTimeIntegrityModel.startDateSeconds = startDateSeconds; + realTimeIntegrityModel.endDateSeconds = endDateSeconds; + realTimeIntegrityModel.publishDateSeconds = publishDateSeconds; + realTimeIntegrityModel.advisoryNumber = android::String16(jniAdvisoryNumber.c_str()); + realTimeIntegrityModel.advisoryType = android::String16(jniAdvisoryType.c_str()); + realTimeIntegrityModels.push_back(realTimeIntegrityModel); + env->DeleteLocalRef(badSignalTypesObj); + env->DeleteLocalRef(realTimeIntegrityModelObj); + } +} + +void GnssAssistanceUtil::setGnssSignalType(JNIEnv* env, jobject gnssSignalTypeObj, + GnssSignalType& gnssSignalType) { + if (gnssSignalTypeObj == nullptr) { + ALOGE("gnssSignalTypeObj is null"); + return; + } + jint constellationType = + env->CallIntMethod(gnssSignalTypeObj, method_gnssSignalTypeGetConstellationType); + jdouble carrierFrequencyHz = + env->CallIntMethod(gnssSignalTypeObj, method_gnssSignalTypeGetCarrierFrequencyHz); + jstring codeType = static_cast<jstring>( + env->CallObjectMethod(gnssSignalTypeObj, method_gnssSignalTypeGetCodeType)); + ScopedJniString jniCodeType{env, codeType}; + + gnssSignalType.constellation = static_cast<GnssConstellationType>(constellationType); + gnssSignalType.carrierFrequencyHz = static_cast<int32_t>(carrierFrequencyHz); + gnssSignalType.codeType = std::string(jniCodeType.c_str()); +} + +void GnssAssistanceUtil::setTimeModels(JNIEnv* env, jobject timeModelsObj, + std::vector<TimeModel>& timeModels) { + if (timeModelsObj == nullptr) return; + auto len = env->CallIntMethod(timeModelsObj, method_listSize); + for (uint16_t i = 0; i < len; ++i) { + jobject timeModelObj = env->CallObjectMethod(timeModelsObj, method_listGet, i); + TimeModel timeModel; + jint toGnss = env->CallIntMethod(timeModelObj, method_timeModelsGetToGnss); + jlong timeOfWeek = env->CallLongMethod(timeModelObj, method_timeModelsGetTimeOfWeek); + jint weekNumber = env->CallIntMethod(timeModelObj, method_timeModelsGetWeekNumber); + jdouble a0 = env->CallDoubleMethod(timeModelObj, method_timeModelsGetA0); + jdouble a1 = env->CallDoubleMethod(timeModelObj, method_timeModelsGetA1); + timeModel.toGnss = static_cast<GnssConstellationType>(toGnss); + timeModel.timeOfWeek = timeOfWeek; + timeModel.weekNumber = static_cast<int32_t>(weekNumber); + timeModel.a0 = a0; + timeModel.a1 = a1; + timeModels.push_back(timeModel); + env->DeleteLocalRef(timeModelObj); + } +} + +void GnssAssistanceUtil::setLeapSecondsModel(JNIEnv* env, jobject leapSecondsModelObj, + LeapSecondsModel& leapSecondsModel) { + if (leapSecondsModelObj == nullptr) { + leapSecondsModel.leapSeconds = -1; + return; + } + jint dayNumberLeapSecondsFuture = + env->CallIntMethod(leapSecondsModelObj, + method_leapSecondsModelGetDayNumberLeapSecondsFuture); + jint leapSeconds = + env->CallIntMethod(leapSecondsModelObj, method_leapSecondsModelGetLeapSeconds); + jint leapSecondsFuture = + env->CallIntMethod(leapSecondsModelObj, method_leapSecondsModelGetLeapSecondsFuture); + jint weekNumberLeapSecondsFuture = + env->CallIntMethod(leapSecondsModelObj, + method_leapSecondsModelGetWeekNumberLeapSecondsFuture); + leapSecondsModel.dayNumberLeapSecondsFuture = static_cast<int32_t>(dayNumberLeapSecondsFuture); + leapSecondsModel.leapSeconds = static_cast<int32_t>(leapSeconds); + leapSecondsModel.leapSecondsFuture = static_cast<int32_t>(leapSecondsFuture); + leapSecondsModel.weekNumberLeapSecondsFuture = + static_cast<int32_t>(weekNumberLeapSecondsFuture); +} + +void GnssAssistanceUtil::setSatelliteEphemerisTime(JNIEnv* env, jobject satelliteEphemerisTimeObj, + SatelliteEphemerisTime& satelliteEphemerisTime) { + if (satelliteEphemerisTimeObj == nullptr) return; + jdouble iode = + env->CallDoubleMethod(satelliteEphemerisTimeObj, method_satelliteEphemerisTimeGetIode); + jdouble toeSeconds = env->CallDoubleMethod(satelliteEphemerisTimeObj, + method_satelliteEphemerisTimeGetToeSeconds); + jint weekNumber = env->CallIntMethod(satelliteEphemerisTimeObj, + method_satelliteEphemerisTimeGetWeekNumber); + satelliteEphemerisTime.iode = iode; + satelliteEphemerisTime.toeSeconds = toeSeconds; + satelliteEphemerisTime.weekNumber = weekNumber; +} + +void GnssAssistanceUtil::setKeplerianOrbitModel(JNIEnv* env, jobject keplerianOrbitModelObj, + KeplerianOrbitModel& keplerianOrbitModel) { + if (keplerianOrbitModelObj == nullptr) return; + jdouble rootA = + env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetRootA); + jdouble eccentricity = env->CallDoubleMethod(keplerianOrbitModelObj, + method_keplerianOrbitModelGetEccentricity); + jdouble m0 = env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetM0); + jdouble omega = + env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetOmega); + jdouble omegaDot = + env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetOmegaDot); + jdouble deltaN = + env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetDeltaN); + jdouble iDot = env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetIDot); + jobject secondOrderHarmonicPerturbationObj = + env->CallObjectMethod(keplerianOrbitModelObj, + method_keplerianOrbitModelGetSecondOrderHarmonicPerturbation); + jdouble cic = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj, + method_secondOrderHarmonicPerturbationGetCic); + jdouble cis = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj, + method_secondOrderHarmonicPerturbationGetCis); + jdouble crs = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj, + method_secondOrderHarmonicPerturbationGetCrs); + jdouble crc = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj, + method_secondOrderHarmonicPerturbationGetCrc); + jdouble cuc = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj, + method_secondOrderHarmonicPerturbationGetCuc); + jdouble cus = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj, + method_secondOrderHarmonicPerturbationGetCus); + keplerianOrbitModel.rootA = rootA; + keplerianOrbitModel.eccentricity = eccentricity; + keplerianOrbitModel.m0 = m0; + keplerianOrbitModel.omega = omega; + keplerianOrbitModel.omegaDot = omegaDot; + keplerianOrbitModel.deltaN = deltaN; + keplerianOrbitModel.iDot = iDot; + keplerianOrbitModel.secondOrderHarmonicPerturbation.cic = cic; + keplerianOrbitModel.secondOrderHarmonicPerturbation.cis = cis; + keplerianOrbitModel.secondOrderHarmonicPerturbation.crs = crs; + keplerianOrbitModel.secondOrderHarmonicPerturbation.crc = crc; + keplerianOrbitModel.secondOrderHarmonicPerturbation.cuc = cuc; + keplerianOrbitModel.secondOrderHarmonicPerturbation.cus = cus; + env->DeleteLocalRef(secondOrderHarmonicPerturbationObj); +} + +void GnssAssistanceUtil::setKlobucharIonosphericModel( + JNIEnv* env, jobject klobucharIonosphericModelObj, + KlobucharIonosphericModel& klobucharIonosphericModel) { + if (klobucharIonosphericModelObj == nullptr) return; + jdouble alpha0 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetAlpha0); + jdouble alpha1 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetAlpha1); + jdouble alpha2 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetAlpha2); + jdouble alpha3 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetAlpha3); + jdouble beta0 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetBeta0); + jdouble beta1 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetBeta1); + jdouble beta2 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetBeta2); + jdouble beta3 = env->CallDoubleMethod(klobucharIonosphericModelObj, + method_klobucharIonosphericModelGetBeta3); + klobucharIonosphericModel.alpha0 = alpha0; + klobucharIonosphericModel.alpha1 = alpha1; + klobucharIonosphericModel.alpha2 = alpha2; + klobucharIonosphericModel.alpha3 = alpha3; + klobucharIonosphericModel.beta0 = beta0; + klobucharIonosphericModel.beta1 = beta1; + klobucharIonosphericModel.beta2 = beta2; + klobucharIonosphericModel.beta3 = beta3; +} + +void GnssAssistanceUtil::setUtcModel(JNIEnv* env, jobject utcModelObj, UtcModel& utcModel) { + if (utcModelObj == nullptr) { + utcModel.weekNumber = -1; + return; + } + jdouble a0 = env->CallDoubleMethod(utcModelObj, method_utcModelGetA0); + jdouble a1 = env->CallDoubleMethod(utcModelObj, method_utcModelGetA1); + jlong timeOfWeek = env->CallLongMethod(utcModelObj, method_utcModelGetTimeOfWeek); + jint weekNumber = env->CallIntMethod(utcModelObj, method_utcModelGetWeekNumber); + utcModel.a0 = a0; + utcModel.a1 = a1; + utcModel.timeOfWeek = timeOfWeek; + utcModel.weekNumber = static_cast<int32_t>(weekNumber); +} + +void GnssAssistanceUtil::setGnssAlmanac(JNIEnv* env, jobject gnssAlmanacObj, + GnssAlmanac& gnssAlmanac) { + if (gnssAlmanacObj == nullptr) { + gnssAlmanac.weekNumber = -1; + return; + } + jlong issueDateMillis = + env->CallLongMethod(gnssAlmanacObj, method_gnssAlmanacGetIssueDateMillis); + jint ioda = env->CallIntMethod(gnssAlmanacObj, method_gnssAlmanacGetIoda); + jint weekNumber = env->CallIntMethod(gnssAlmanacObj, method_gnssAlmanacGetWeekNumber); + jlong toaSeconds = env->CallLongMethod(gnssAlmanacObj, method_gnssAlmanacGetToaSeconds); + jboolean isCompleteAlmanacProvided = + env->CallBooleanMethod(gnssAlmanacObj, method_gnssAlmanacIsCompleteAlmanacProvided); + gnssAlmanac.issueDateMs = issueDateMillis; + gnssAlmanac.ioda = ioda; + gnssAlmanac.weekNumber = weekNumber; + gnssAlmanac.toaSeconds = toaSeconds; + gnssAlmanac.isCompleteAlmanacProvided = isCompleteAlmanacProvided; + + jobject satelliteAlmanacsListObj = + env->CallObjectMethod(gnssAlmanacObj, method_gnssAlmanacGetSatelliteAlmanacs); + auto len = env->CallIntMethod(satelliteAlmanacsListObj, method_listSize); + std::vector<GnssSatelliteAlmanac> list(len); + for (uint16_t i = 0; i < len; ++i) { + jobject gnssSatelliteAlmanacObj = + env->CallObjectMethod(satelliteAlmanacsListObj, method_listGet, i); + if (gnssSatelliteAlmanacObj == nullptr) continue; + GnssSatelliteAlmanac gnssSatelliteAlmanac; + jint svid = env->CallIntMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetSvid); + jint svHealth = + env->CallIntMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetSvHealth); + jdouble af0 = env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetAf0); + jdouble af1 = env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetAf1); + jdouble eccentricity = env->CallDoubleMethod(gnssSatelliteAlmanacObj, + method_satelliteAlmanacGetEccentricity); + jdouble inclination = env->CallDoubleMethod(gnssSatelliteAlmanacObj, + method_satelliteAlmanacGetInclination); + jdouble m0 = env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetM0); + jdouble omega = + env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetOmega); + jdouble omega0 = + env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetOmega0); + jdouble omegaDot = + env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetOmegaDot); + jdouble rootA = + env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetRootA); + gnssSatelliteAlmanac.svid = static_cast<int32_t>(svid); + gnssSatelliteAlmanac.svHealth = static_cast<int32_t>(svHealth); + gnssSatelliteAlmanac.af0 = af0; + gnssSatelliteAlmanac.af1 = af1; + gnssSatelliteAlmanac.eccentricity = eccentricity; + gnssSatelliteAlmanac.inclination = inclination; + gnssSatelliteAlmanac.m0 = m0; + gnssSatelliteAlmanac.omega = omega; + gnssSatelliteAlmanac.omega0 = omega0; + gnssSatelliteAlmanac.omegaDot = omegaDot; + gnssSatelliteAlmanac.rootA = rootA; + list.at(i) = gnssSatelliteAlmanac; + env->DeleteLocalRef(gnssSatelliteAlmanacObj); + } + gnssAlmanac.satelliteAlmanacs = list; + env->DeleteLocalRef(satelliteAlmanacsListObj); +} + +void GnssAssistanceUtil::setAuxiliaryInformation(JNIEnv* env, jobject auxiliaryInformationObj, + AuxiliaryInformation& auxiliaryInformation) { + if (auxiliaryInformationObj == nullptr) { + auxiliaryInformation.svid = -1; + return; + } + jint svid = env->CallIntMethod(auxiliaryInformationObj, method_auxiliaryInformationGetSvid); + jobject availableSignalTypesObj = + env->CallObjectMethod(auxiliaryInformationObj, + method_auxiliaryInformationGetAvailableSignalTypes); + auto size = env->CallIntMethod(availableSignalTypesObj, method_listSize); + std::vector<GnssSignalType> availableSignalTypes(size); + for (uint16_t i = 0; i < size; ++i) { + jobject availableSignalTypeObj = + env->CallObjectMethod(availableSignalTypesObj, method_listGet, i); + GnssSignalType availableSignalType; + setGnssSignalType(env, availableSignalTypeObj, availableSignalType); + availableSignalTypes.at(i) = availableSignalType; + env->DeleteLocalRef(availableSignalTypeObj); + } + jint frequencyChannelNumber = + env->CallIntMethod(auxiliaryInformationObj, + method_auxiliaryInformationGetFrequencyChannelNumber); + jint satType = + env->CallIntMethod(auxiliaryInformationObj, method_auxiliaryInformationGetSatType); + auxiliaryInformation.svid = static_cast<int32_t>(svid); + auxiliaryInformation.availableSignalTypes = availableSignalTypes; + auxiliaryInformation.frequencyChannelNumber = static_cast<int32_t>(frequencyChannelNumber); + auxiliaryInformation.satType = static_cast<BeidouB1CSatelliteOrbitType>(satType); + env->DeleteLocalRef(availableSignalTypesObj); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssAssistance.h b/services/core/jni/gnss/GnssAssistance.h new file mode 100644 index 000000000000..ee97e19371f8 --- /dev/null +++ b/services/core/jni/gnss/GnssAssistance.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2024 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. + */ + +#ifndef _ANDROID_SERVER_GNSSASSITANCE_H +#define _ANDROID_SERVER_GNSSASSITANCE_H + +#include <sys/stat.h> +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include <android/hardware/gnss/gnss_assistance/BnGnssAssistanceInterface.h> +#include <log/log.h> + +#include "GnssAssistanceCallback.h" +#include "jni.h" + +namespace android::gnss { + +using IGnssAssistanceInterface = android::hardware::gnss::gnss_assistance::IGnssAssistanceInterface; +using IGnssAssistanceCallback = android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback; +using BeidouAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance::BeidouAssistance; +using BeidouSatelliteEphemeris = android::hardware::gnss::gnss_assistance::BeidouSatelliteEphemeris; +using GalileoAssistance = + android::hardware::gnss::gnss_assistance::GnssAssistance::GalileoAssistance; +using GalileoSatelliteEphemeris = + android::hardware::gnss::gnss_assistance::GalileoSatelliteEphemeris; +using GalileoIonosphericModel = android::hardware::gnss::gnss_assistance::GalileoIonosphericModel; +using GlonassAssistance = + android::hardware::gnss::gnss_assistance::GnssAssistance::GlonassAssistance; +using GlonassAlmanac = android::hardware::gnss::gnss_assistance::GlonassAlmanac; +using GlonassSatelliteEphemeris = + android::hardware::gnss::gnss_assistance::GlonassSatelliteEphemeris; +using GnssAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance; +using GnssSignalType = android::hardware::gnss::GnssSignalType; +using GpsAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance::GpsAssistance; +using QzssAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance::QzssAssistance; +using GnssAlmanac = android::hardware::gnss::gnss_assistance::GnssAlmanac; +using GnssSatelliteCorrections = + android::hardware::gnss::gnss_assistance::GnssAssistance::GnssSatelliteCorrections; +using GpsSatelliteEphemeris = android::hardware::gnss::gnss_assistance::GpsSatelliteEphemeris; +using SatelliteEphemerisTime = android::hardware::gnss::gnss_assistance::SatelliteEphemerisTime; +using UtcModel = android::hardware::gnss::gnss_assistance::UtcModel; +using LeapSecondsModel = android::hardware::gnss::gnss_assistance::LeapSecondsModel; +using KeplerianOrbitModel = android::hardware::gnss::gnss_assistance::KeplerianOrbitModel; +using KlobucharIonosphericModel = + android::hardware::gnss::gnss_assistance::KlobucharIonosphericModel; +using TimeModel = android::hardware::gnss::gnss_assistance::TimeModel; +using RealTimeIntegrityModel = android::hardware::gnss::gnss_assistance::RealTimeIntegrityModel; +using AuxiliaryInformation = android::hardware::gnss::gnss_assistance::AuxiliaryInformation; + +void GnssAssistance_class_init_once(JNIEnv* env, jclass clazz); + +class GnssAssistanceInterface { +public: + GnssAssistanceInterface(const sp<IGnssAssistanceInterface>& iGnssAssistance); + jboolean injectGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj); + jboolean setCallback(const sp<IGnssAssistanceCallback>& callback); + +private: + const sp<IGnssAssistanceInterface> mGnssAssistanceInterface; +}; + +struct GnssAssistanceUtil { + static void setGlonassAssistance(JNIEnv* env, jobject glonassAssistanceObj, + GlonassAssistance& galileoAssistance); + static void setGlonassSatelliteEphemeris( + JNIEnv* env, jobject glonassSatelliteEphemerisObj, + std::vector<GlonassSatelliteEphemeris>& glonassSatelliteEphemerisList); + static void setGlonassAlmanac(JNIEnv* env, jobject glonassAlmanacObj, + GlonassAlmanac& glonassAlmanac); + static void setBeidouAssistance(JNIEnv* env, jobject beidouAssistanceObj, + BeidouAssistance& beidouAssistance); + static void setBeidouSatelliteEphemeris( + JNIEnv* env, jobject beidouSatelliteEphemerisObj, + std::vector<BeidouSatelliteEphemeris>& beidouSatelliteEphemerisList); + static void setGalileoAssistance(JNIEnv* env, jobject galileoAssistanceObj, + GalileoAssistance& galileoAssistance); + static void setGalileoSatelliteEphemeris( + JNIEnv* env, jobject galileoSatelliteEphemerisObj, + std::vector<GalileoSatelliteEphemeris>& galileoSatelliteEphemerisList); + static void setGaliloKlobucharIonosphericModel(JNIEnv* env, jobject galileoIonosphericModelObj, + GalileoIonosphericModel& ionosphericModel); + static void setGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj, + GnssAssistance& gnssAssistance); + static void setGpsAssistance(JNIEnv* env, jobject gpsAssistanceObj, + GpsAssistance& gpsAssistance); + template <class T> + static void setGpsOrQzssSatelliteEphemeris(JNIEnv* env, jobject satelliteEphemerisObj, + std::vector<T>& satelliteEphemeris); + static void setQzssAssistance(JNIEnv* env, jobject qzssAssistanceObj, + QzssAssistance& qzssAssistance); + static void setGnssAlmanac(JNIEnv* env, jobject gnssAlmanacObj, GnssAlmanac& gnssAlmanac); + static void setGnssSignalType(JNIEnv* env, jobject gnssSignalTypeObj, + GnssSignalType& gnssSignalType); + static void setKeplerianOrbitModel(JNIEnv* env, jobject keplerianOrbitModelObj, + KeplerianOrbitModel& keplerianOrbitModel); + static void setKlobucharIonosphericModel(JNIEnv* env, jobject klobucharIonosphericModelObj, + KlobucharIonosphericModel& klobucharIonosphericModel); + static void setTimeModels(JNIEnv* env, jobject timeModelsObj, + std::vector<TimeModel>& timeModels); + static void setLeapSecondsModel(JNIEnv* env, jobject leapSecondsModelObj, + LeapSecondsModel& leapSecondsModel); + static void setRealTimeIntegrityModels( + JNIEnv* env, jobject realTimeIntegrityModelsObj, + std::vector<RealTimeIntegrityModel>& realTimeIntegrityModels); + + static void setSatelliteEphemerisTime(JNIEnv* env, jobject satelliteEphemerisTimeObj, + SatelliteEphemerisTime& satelliteEphemerisTime); + static void setUtcModel(JNIEnv* env, jobject utcModelObj, UtcModel& utcModel); + static void setSatelliteCorrections( + JNIEnv* env, jobject satelliteCorrectionsObj, + std::vector<GnssSatelliteCorrections>& satelliteCorrections); + static void setAuxiliaryInformation(JNIEnv* env, jobject auxiliaryInformationObj, + AuxiliaryInformation& auxiliaryInformation); +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSSASSITANCE__H diff --git a/services/core/jni/gnss/GnssAssistanceCallback.cpp b/services/core/jni/gnss/GnssAssistanceCallback.cpp new file mode 100644 index 000000000000..dbb27d72663e --- /dev/null +++ b/services/core/jni/gnss/GnssAssistanceCallback.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 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. + */ + +#define LOG_TAG "GnssAssistanceCbJni" + +#include "GnssAssistanceCallback.h" + +#include "Utils.h" + +namespace { +jmethodID method_gnssAssistanceInjectRequest; +} // anonymous namespace + +namespace android::gnss { + +using binder::Status; +using hardware::Return; +using hardware::Void; + +void GnssAssistanceCallback_class_init_once(JNIEnv* env, jclass clazz) { + method_gnssAssistanceInjectRequest = + env->GetStaticMethodID(clazz, "gnssAssistanceInjectRequest", "()V"); +} + +// Implementation of android::hardware::gnss::gnss_assistance::GnssAssistanceCallback. + +Status GnssAssistanceCallback::injectRequestCb() { + ALOGD("%s.", __func__); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_gnssAssistanceInjectRequest); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssAssistanceCallback.h b/services/core/jni/gnss/GnssAssistanceCallback.h new file mode 100644 index 000000000000..4c8c5fc06730 --- /dev/null +++ b/services/core/jni/gnss/GnssAssistanceCallback.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 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. + */ + +#ifndef _ANDROID_SERVER_GNSS_GNSSASSITANCECALLBACK_H +#define _ANDROID_SERVER_GNSS_GNSSASSITANCECALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include <android/hardware/gnss/gnss_assistance/BnGnssAssistanceCallback.h> +#include <log/log.h> + +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +void GnssAssistanceCallback_class_init_once(JNIEnv* env, jclass clazz); + +/* + * GnssAssistanceCallback class implements the callback methods required by the + * android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback interface. + */ +class GnssAssistanceCallback : public hardware::gnss::gnss_assistance::BnGnssAssistanceCallback { +public: + GnssAssistanceCallback() {} + binder::Status injectRequestCb() override; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSASSITANCECALLBACK_H diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index 42e457c97fd4..bc5c427e3ccb 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -51,7 +51,6 @@ import android.credentials.ISetEnabledProvidersCallback; import android.credentials.PrepareGetCredentialResponseInternal; import android.credentials.RegisterCredentialDescriptionRequest; import android.credentials.UnregisterCredentialDescriptionRequest; -import android.credentials.flags.Flags; import android.os.Binder; import android.os.CancellationSignal; import android.os.IBinder; @@ -538,34 +537,31 @@ public final class CredentialManagerService final int userId = UserHandle.getCallingUserId(); final int callingUid = Binder.getCallingUid(); - if (Flags.safeguardCandidateCredentialsApiCaller()) { - try { - String credentialManagerAutofillCompName = mContext.getResources().getString( - R.string.config_defaultCredentialManagerAutofillService); - ComponentName componentName = ComponentName.unflattenFromString( - credentialManagerAutofillCompName); - if (componentName == null) { - throw new SecurityException( - "Credential Autofill service does not exist on this device."); - } - PackageManager pm = mContext.createContextAsUser( - UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager(); - String callingProcessPackage = pm.getNameForUid(callingUid); - if (callingProcessPackage == null) { - throw new SecurityException( - "Couldn't determine the identity of the caller."); - } - if (!Objects.equals(componentName.getPackageName(), callingProcessPackage)) { - throw new SecurityException(callingProcessPackage - + " is not the device's credential autofill package."); - } - } catch (Resources.NotFoundException e) { + try { + String credentialManagerAutofillCompName = mContext.getResources().getString( + R.string.config_defaultCredentialManagerAutofillService); + ComponentName componentName = ComponentName.unflattenFromString( + credentialManagerAutofillCompName); + if (componentName == null) { throw new SecurityException( "Credential Autofill service does not exist on this device."); } + PackageManager pm = mContext.createContextAsUser( + UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager(); + String callingProcessPackage = pm.getNameForUid(callingUid); + if (callingProcessPackage == null) { + throw new SecurityException( + "Couldn't determine the identity of the caller."); + } + if (!Objects.equals(componentName.getPackageName(), callingProcessPackage)) { + throw new SecurityException(callingProcessPackage + + " is not the device's credential autofill package."); + } + } catch (Resources.NotFoundException e) { + throw new SecurityException( + "Credential Autofill service does not exist on this device."); } - // New request session, scoped for this request only. final GetCandidateRequestSession session = new GetCandidateRequestSession( diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 51ed6bb2aa40..f055febca3d5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -276,6 +276,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH; import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; import static com.android.server.devicepolicy.DevicePolicyEngine.DEFAULT_POLICY_SIZE_LIMIT; +import static com.android.server.devicepolicy.DevicePolicyEngine.SYSTEM_SUPERVISION_ROLE; import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE; import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__COPE; import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__DEVICE_OWNER; @@ -16296,6 +16297,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } + /** + * When multiple admins enforce a policy, this method returns an admin according to this order: + * 1. Supervision + * 2. DPC + * + * Otherwise, it returns any other admin. + */ private android.app.admin.EnforcingAdmin getEnforcingAdminInternal(int userId, String identifier) { Objects.requireNonNull(identifier); @@ -16304,16 +16312,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (admins.isEmpty()) { return null; } - - final EnforcingAdmin admin; if (admins.size() == 1) { - admin = admins.iterator().next(); - } else { - Optional<EnforcingAdmin> dpc = admins.stream() - .filter(a -> a.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)).findFirst(); - admin = dpc.orElseGet(() -> admins.stream().findFirst().get()); + return admins.iterator().next().getParcelableAdmin(); + } + Optional<EnforcingAdmin> supervision = admins.stream() + .filter(a -> a.hasAuthority( + EnforcingAdmin.getRoleAuthorityOf(SYSTEM_SUPERVISION_ROLE))) + .findFirst(); + if (supervision.isPresent()) { + return supervision.get().getParcelableAdmin(); + } + Optional<EnforcingAdmin> dpc = admins.stream() + .filter(a -> a.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)).findFirst(); + if (dpc.isPresent()) { + return dpc.get().getParcelableAdmin(); } - return admin == null ? null : admin.getParcelableAdmin(); + return admins.iterator().next().getParcelableAdmin(); } private <V> Set<EnforcingAdmin> getEnforcingAdminsForIdentifier(int userId, String identifier) { diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java index de78271acddc..69e856de401a 100644 --- a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java +++ b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java @@ -325,7 +325,8 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } if (newState != INVALID_DEVICE_STATE_IDENTIFIER && newState != mLastReportedState) { - if (Trace.isTagEnabled(TRACE_TAG_SYSTEM_SERVER)) { + if (mLastHingeAngleSensorEvent != null + && Trace.isTagEnabled(TRACE_TAG_SYSTEM_SERVER)) { Trace.instant(TRACE_TAG_SYSTEM_SERVER, "[Device state changed] Last hinge sensor event timestamp: " + mLastHingeAngleSensorEvent.timestamp); diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java index 6adb01ccf11f..e898c833b321 100644 --- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java +++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java @@ -18,7 +18,6 @@ package com.android.server.inputmethod; import static com.google.common.truth.Truth.assertThat; -import android.platform.test.ravenwood.RavenwoodRule; import android.view.WindowManager; import androidx.annotation.NonNull; @@ -28,7 +27,6 @@ import com.android.server.wm.WindowManagerInternal; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -42,10 +40,6 @@ public final class UserDataRepositoryTest { private static final int ANY_USER_ID = 1; - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true).build(); - @Mock private InputMethodManagerService mMockInputMethodManagerService; diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java index 9117cc8e5ab8..a38ecc8523b1 100644 --- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java +++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java @@ -3186,6 +3186,32 @@ public class VpnTest extends VpnTestBase { assertEquals(profile, ikev2VpnProfile.toVpnProfile()); } + @Test + public void testStartAlwaysOnVpnOnSafeMode() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + setMockedUsers(PRIMARY_USER); + + // UID checks must return a different UID; otherwise it'll be treated as already prepared. + final int uid = Process.myUid() + 1; + when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt())) + .thenReturn(uid); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + + setAndVerifyAlwaysOnPackage(vpn, uid, false); + assertTrue(vpn.startAlwaysOnVpn()); + assertEquals(TEST_VPN_PKG, vpn.getAlwaysOnPackage()); + + // Simulate safe mode and restart the always-on VPN to verify the always-on package is not + // reset. + doReturn(null).when(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG)); + doReturn(null).when(mPackageManager).queryIntentServicesAsUser( + any(), any(), eq(PRIMARY_USER.id)); + doReturn(true).when(mPackageManager).isSafeMode(); + assertFalse(vpn.startAlwaysOnVpn()); + assertEquals(TEST_VPN_PKG, vpn.getAlwaysOnPackage()); + } + // Make it public and un-final so as to spy it public class TestDeps extends Vpn.Dependencies { TestDeps() {} diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java index e678acc092e9..987b9c6427d8 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java @@ -21,6 +21,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import static com.android.server.am.ActivityManagerService.Injector; 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; @@ -625,6 +626,60 @@ public class ApplicationStartInfoTest { assertTrue(startInfo.equals(startInfoFromParcel)); } + /** Test that new timestamps are added to the correct record (the most recently created one). */ + @Test + public void testTimestampAddedToCorrectRecord() throws Exception { + // Use a different start timestamp for each record so we can identify which was added to. + final long startTimeRecord1 = 123L; + final long startTimeRecord2 = 456L; + + final long forkTime = 789L; + + // Create a process record to use with all starts. + ProcessRecord app = makeProcessRecord( + APP_1_PID_1, // pid + APP_1_UID, // uid + APP_1_UID, // packageUid + null, // definingUid + APP_1_PROCESS_NAME, // processName + APP_1_PACKAGE_NAME); // packageName + + // Trigger a start info record. + mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord1, app, + buildIntent(COMPONENT), false /* isAlarm */); + + // Wait at least 1 ms for monotonic time to increase. + sleep(1); + + // Verify the record was added successfully. + ArrayList<ApplicationStartInfo> list = new ArrayList<ApplicationStartInfo>(); + mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list); + assertEquals(1, list.size()); + assertEquals(startTimeRecord1, list.get(0).getStartupTimestamps().get(0).longValue()); + + // Now trigger another start info record. + mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord2, app, + buildIntent(COMPONENT), false /* isAlarm */); + + // Add a timestamp to the most recent record. + mAppStartInfoTracker.addTimestampToStart( + app, forkTime, ApplicationStartInfo.START_TIMESTAMP_FORK); + + // Verify the record was added successfully. + list.clear(); + mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list); + assertEquals(2, list.size()); + assertEquals(startTimeRecord2, list.get(0).getStartupTimestamps().get(0).longValue()); + assertEquals(startTimeRecord1, list.get(1).getStartupTimestamps().get(0).longValue()); + + // Verify that the new timestamp is set correctly on the 2nd record that was added and not + // on the first. + assertEquals(forkTime, list.get(0).getStartupTimestamps() + .get(ApplicationStartInfo.START_TIMESTAMP_FORK).longValue()); + assertFalse(list.get(1).getStartupTimestamps().containsKey( + ApplicationStartInfo.START_TIMESTAMP_FORK)); + } + private static <T> void setFieldValue(Class clazz, Object obj, String fieldName, T val) { try { Field field = clazz.getDeclaredField(fieldName); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index e094111c327a..773114e4839d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -74,6 +74,10 @@ import static com.android.server.am.ProcessList.SERVICE_ADJ; import static com.android.server.am.ProcessList.SERVICE_B_ADJ; import static com.android.server.am.ProcessList.UNKNOWN_ADJ; import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -544,7 +548,7 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); WindowProcessController wpc = app.getWindowProcessController(); doReturn(true).when(wpc).hasActivities(); - doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE) + doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE) .when(wpc).getActivityStateFlags(); setWakefulness(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app); @@ -553,28 +557,58 @@ public class MockingOomAdjusterTests { assertFalse(app.mState.isCached()); assertFalse(app.mState.isEmpty()); assertEquals("vis-activity", app.mState.getAdjType()); + assertCpuTime(app); - doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE + doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE | WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) .when(wpc).getActivityStateFlags(); updateOomAdj(app); assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP); assertEquals("resumed-split-screen-activity", app.mState.getAdjType()); + assertCpuTime(app); - doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE + doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE | WindowProcessController.ACTIVITY_STATE_FLAG_PERCEPTIBLE_FREEFORM) .when(wpc).getActivityStateFlags(); updateOomAdj(app); assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP); assertEquals("perceptible-freeform-activity", app.mState.getAdjType()); + assertCpuTime(app); - doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE + doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE | WindowProcessController.ACTIVITY_STATE_FLAG_VISIBLE_MULTI_WINDOW_MODE) .when(wpc).getActivityStateFlags(); updateOomAdj(app); assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_FOREGROUND_WINDOW); assertEquals("vis-multi-window-activity", app.mState.getAdjType()); + assertCpuTime(app); + } + @SuppressWarnings("GuardedBy") + @Test + public void testUpdateOomAdj_DoOne_PausingStoppingActivities() { + ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); + WindowProcessController wpc = app.getWindowProcessController(); + doReturn(true).when(wpc).hasActivities(); + doReturn(ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED).when(wpc).getActivityStateFlags(); + setWakefulness(PowerManagerInternal.WAKEFULNESS_AWAKE); + updateOomAdj(app); + assertProcStates(app, PROCESS_STATE_TOP, PERCEPTIBLE_APP_ADJ, SCHED_GROUP_DEFAULT, + "pause-activity"); + assertCpuTime(app); + + doReturn(ACTIVITY_STATE_FLAG_IS_STOPPING).when(wpc).getActivityStateFlags(); + updateOomAdj(app); + assertProcStates(app, PROCESS_STATE_LAST_ACTIVITY, PERCEPTIBLE_APP_ADJ, + SCHED_GROUP_BACKGROUND, "stop-activity"); + assertCpuTime(app); + + doReturn(ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING).when(wpc).getActivityStateFlags(); + updateOomAdj(app); + assertProcStates(app, PROCESS_STATE_CACHED_ACTIVITY, CACHED_APP_MIN_ADJ, + SCHED_GROUP_BACKGROUND, "cch-act"); + assertNoCpuTime(app); } @SuppressWarnings("GuardedBy") @@ -750,7 +784,8 @@ public class MockingOomAdjusterTests { ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); WindowProcessController wpc = app.getWindowProcessController(); - doReturn(true).when(wpc).hasVisibleActivities(); + doReturn(true).when(wpc).hasActivities(); + doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE).when(wpc).getActivityStateFlags(); final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); @@ -3483,12 +3518,14 @@ public class MockingOomAdjusterTests { // EXPECT: stale-perceptible-act adjustment doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) .when(wpc).getActivityStateFlags(); + assertNoCpuTime(app); doReturn(now - OomAdjuster.PERCEPTIBLE_TASK_TIMEOUT_MILLIS).when( wpc).getPerceptibleTaskStoppedTimeMillis(); updateOomAdj(app); assertProcStates(app, PROCESS_STATE_LAST_ACTIVITY, PREVIOUS_APP_ADJ, SCHED_GROUP_BACKGROUND, "stale-perceptible-act"); + assertNoCpuTime(app); // GIVEN: perceptible adjustment is is disabled // EXPECT: no perceptible adjustment @@ -3498,15 +3535,17 @@ public class MockingOomAdjusterTests { updateOomAdj(app); assertProcStates(app, PROCESS_STATE_CACHED_ACTIVITY, CACHED_APP_MIN_ADJ, SCHED_GROUP_BACKGROUND, "cch-act"); + assertNoCpuTime(app); // GIVEN: perceptible app is in foreground // EXPECT: no perceptible adjustment - doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE) + doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE) .when(wpc).getActivityStateFlags(); doReturn(now).when(wpc).getPerceptibleTaskStoppedTimeMillis(); updateOomAdj(app); assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_DEFAULT, "vis-activity"); + assertCpuTime(app); } @SuppressWarnings("GuardedBy") diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java index 4b91d8418fc3..28d39fd8cea2 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_AMBIENT; import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import android.view.Display; import androidx.test.filters.SmallTest; @@ -35,15 +34,10 @@ import org.junit.runner.RunWith; @SmallTest @SuppressWarnings("GuardedBy") public class AmbientDisplayPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final long MINUTE_IN_MS = 60 * 1000; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0, 10.0) .setNumDisplays(1); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java index ce451c2a842a..7f03953204d0 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -35,16 +34,11 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class AudioPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_AUDIO, 360.0); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java index ec8ede06099f..7faa29572b18 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java @@ -23,7 +23,6 @@ import static org.mockito.Mockito.mock; import android.content.Context; import android.os.BatteryManager; import android.os.BatteryUsageStats; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -38,14 +37,9 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class BatteryChargeCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java index ad05b5124955..8791c2f93ab8 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java @@ -25,13 +25,11 @@ import static org.junit.Assert.assertTrue; import android.app.ActivityManager; import android.os.BatteryStats; import android.os.WorkSource; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArrayMap; import android.view.Display; import androidx.test.filters.SmallTest; -import org.junit.Rule; import org.junit.Test; /** @@ -39,11 +37,6 @@ import org.junit.Test; */ public class BatteryStatsBackgroundStatsTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final int UID = 10500; /** Test that BatteryStatsImpl.Uid.mOnBatteryBackgroundTimeBase works correctly. */ diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java index 4dfc3fcec916..c0d33cb7134a 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals; import android.os.Binder; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArraySet; import androidx.test.filters.SmallTest; @@ -28,7 +27,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.os.BinderCallsStats; import com.android.internal.os.BinderTransactionNameResolver; -import org.junit.Rule; import org.junit.Test; import java.util.ArrayList; @@ -41,11 +39,6 @@ import java.util.Collection; @android.platform.test.annotations.DisabledOnRavenwood(blockedBy = BinderCallsStats.class) public class BatteryStatsBinderCallStatsTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final int TRANSACTION_CODE1 = 100; private static final int TRANSACTION_CODE2 = 101; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java index eff1b7b852d9..b73895c6e42f 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java @@ -40,7 +40,6 @@ import android.os.BatteryStats; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; import android.util.SparseLongArray; import android.view.Display; @@ -57,7 +56,6 @@ import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeRea import com.android.internal.util.ArrayUtils; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -88,11 +86,6 @@ import java.util.Arrays; @RunWith(AndroidJUnit4.class) @SuppressWarnings("SynchronizeOnNonFinalField") public class BatteryStatsCpuTimesTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - @Mock KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; @Mock diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java index 7e40e6b4f71f..503e23347cf6 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java @@ -22,7 +22,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -31,7 +30,6 @@ import com.android.internal.os.BatteryStatsHistoryIterator; import com.android.internal.os.MonotonicClock; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,11 +42,6 @@ import java.util.Random; @SmallTest @SuppressWarnings("GuardedBy") public class BatteryStatsHistoryIteratorTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private final MockClock mMockClock = new MockClock(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java index db3268729f1e..17440930d077 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java @@ -92,7 +92,6 @@ import java.util.List; public class BatteryStatsImplTest { @Rule(order = 0) public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) .setSystemPropertyImmutable("persist.sys.com.android.server.power.feature.flags." + "framework_wakelock_info-override", null) .build(); @@ -150,7 +149,7 @@ public class BatteryStatsImplTest { File systemDir = Files.createTempDirectory("BatteryStatsHistoryTest").toFile(); Context context; - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { context = mock(Context.class); SensorManager sensorManager = mock(SensorManager.class); when(sensorManager.getSensorList(anyInt())).thenReturn(List.of()); @@ -856,7 +855,7 @@ public class BatteryStatsImplTest { } private UidTraffic createUidTraffic(int appUid, long rxBytes, long txBytes) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { UidTraffic uidTraffic = mock(UidTraffic.class); when(uidTraffic.getUid()).thenReturn(appUid); when(uidTraffic.getRxBytes()).thenReturn(rxBytes); @@ -881,7 +880,7 @@ public class BatteryStatsImplTest { long controllerIdleTimeMs, long controllerEnergyUsed, UidTraffic... uidTraffic) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { BluetoothActivityEnergyInfo info = mock(BluetoothActivityEnergyInfo.class); when(info.getTimestampMillis()).thenReturn(timestamp); when(info.getControllerTxTimeMillis()).thenReturn(controllerTxTimeMs); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java index 30ff8005563a..ffb309a211f9 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java @@ -91,7 +91,6 @@ public class BatteryStatsNoteTest { @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) .setSystemPropertyImmutable( "persist.sys.com.android.server.power.feature.flags." + "framework_wakelock_info-override", diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java index b6d49d0ade0a..550df3ae1fa7 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java @@ -23,7 +23,6 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.os.BatteryManager; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -40,11 +39,6 @@ import java.io.IOException; public class BatteryStatsResetTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .createTempDirectory(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java index 96780c322445..018e8c2dbb08 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java @@ -22,12 +22,10 @@ import static org.junit.Assert.assertNull; import android.app.ActivityManager; import android.os.BatteryStats; -import android.platform.test.ravenwood.RavenwoodRule; import android.view.Display; import androidx.test.filters.SmallTest; -import org.junit.Rule; import org.junit.Test; /** @@ -36,11 +34,6 @@ import org.junit.Test; @SmallTest public class BatteryStatsSensorTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final int UID = 10500; private static final int UID_2 = 10501; // second uid for testing pool usage private static final int SENSOR_ID = -10000; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java index 6f683ae5e0c0..882e48da5273 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java @@ -18,13 +18,11 @@ package com.android.server.power.stats; import android.os.BatteryStats; import android.os.Parcel; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import junit.framework.Assert; -import org.junit.Rule; import org.junit.Test; /** @@ -32,11 +30,6 @@ import org.junit.Test; */ @SmallTest public class BatteryStatsServTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final String TAG = "BatteryStatsServTest"; public static class TestServ extends BatteryStatsImpl.Uid.Pkg.Serv { diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java index 93fe8d330d5b..8a1d37b55255 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java @@ -68,18 +68,13 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class BatteryUsageStatsProviderTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private static final long MINUTE_IN_MS = 60 * 1000; private static final double PRECISION = 0.00001; - @Rule(order = 2) + @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345) .createTempDirectory() @@ -94,7 +89,7 @@ public class BatteryUsageStatsProviderTest { @Before public void setup() throws IOException { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { mContext = mock(Context.class); SensorManager sensorManager = mock(SensorManager.class); when(mContext.getSystemService(SensorManager.class)).thenReturn(sensorManager); @@ -420,7 +415,7 @@ public class BatteryUsageStatsProviderTest { Parcel parcel = Parcel.obtain(); parcel.writeParcelable(batteryUsageStats, 0); - if (!RavenwoodRule.isUnderRavenwood()) { + if (!RavenwoodRule.isOnRavenwood()) { assertThat(parcel.dataSize()).isAtMost(128_000); } @@ -579,7 +574,7 @@ public class BatteryUsageStatsProviderTest { MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); accumulateBatteryUsageStats(batteryStats, 10000000, 0); // Accumulate every 200 bytes of battery history - accumulateBatteryUsageStats(batteryStats, 200, 2); + accumulateBatteryUsageStats(batteryStats, 200, 1); accumulateBatteryUsageStats(batteryStats, 50, 5); // Accumulate on every invocation of accumulateBatteryUsageStats accumulateBatteryUsageStats(batteryStats, 0, 7); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java index 097a60ed52c5..dc1c3b4e2b23 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java @@ -37,7 +37,6 @@ import android.os.BatteryUsageStats; import android.os.Parcel; import android.os.UidBatteryConsumer; import android.os.UserBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.Xml; import androidx.test.filters.SmallTest; @@ -46,7 +45,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -64,11 +62,6 @@ import java.util.stream.Collectors; @SmallTest @RunWith(AndroidJUnit4.class) public class BatteryUsageStatsTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final int USER_ID = 42; private static final int APP_UID1 = 271; private static final int APP_UID2 = 314; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java index c9cb0dfa98e4..9552808f0733 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java @@ -50,15 +50,10 @@ import java.util.List; @SmallTest @SuppressWarnings("GuardedBy") public class BluetoothPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE, 10.0) .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX, 50.0) @@ -335,7 +330,7 @@ public class BluetoothPowerCalculatorTest { } private UidTraffic createUidTraffic(int appUid, long rxBytes, long txBytes) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { UidTraffic uidTraffic = mock(UidTraffic.class); when(uidTraffic.getUid()).thenReturn(appUid); when(uidTraffic.getRxBytes()).thenReturn(rxBytes); @@ -356,7 +351,7 @@ public class BluetoothPowerCalculatorTest { private BluetoothActivityEnergyInfo createBtEnergyInfo(long timestamp, int stackState, long txTime, long rxTime, long idleTime, long energyUsed, List<UidTraffic> traffic) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { BluetoothActivityEnergyInfo info = mock(BluetoothActivityEnergyInfo.class); when(info.getTimestampMillis()).thenReturn(timestamp); when(info.getBluetoothStackState()).thenReturn(stackState); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java index 3895cb480847..98ec6de916ec 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java @@ -57,11 +57,6 @@ public class BluetoothPowerStatsCollectorTest { private static final int ISOLATED_UID = 99123; @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setPowerStatsThrottlePeriodMillis(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, 1000); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java index 4cd3857a80bb..6745ffd2700b 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -35,17 +34,12 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class CameraPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP1_UID = Process.FIRST_APPLICATION_UID + 42; private static final int APP2_UID = Process.FIRST_APPLICATION_UID + 43; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CAMERA, 360.0) .initMeasuredEnergyStatsLocked(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java index 527db67a84ae..ee58d7ef5778 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java @@ -32,7 +32,6 @@ import android.os.BatteryStats; import android.os.BatteryUsageStatsQuery; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseArray; import androidx.test.filters.SmallTest; @@ -56,11 +55,6 @@ import org.mockito.MockitoAnnotations; @SmallTest @SuppressWarnings("GuardedBy") public class CpuPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; @@ -68,7 +62,7 @@ public class CpuPowerCalculatorTest { private static final int NUM_CPU_FREQS = 2 + 2; // 2 clusters * 2 freqs each - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720) .setCpuScalingPolicy(0, new int[]{0, 1}, new int[]{100, 200}) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java index 1fea46256b12..70f03701f935 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java @@ -32,7 +32,6 @@ import android.os.BatteryConsumer; import android.os.ConditionVariable; import android.os.Handler; import android.os.HandlerThread; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.IndentingPrintWriter; import android.util.SparseArray; @@ -46,7 +45,6 @@ import com.android.internal.os.PowerStats; import com.android.server.power.stats.format.CpuPowerStatsLayout; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -60,11 +58,6 @@ import java.io.StringWriter; @SmallTest public class CpuPowerStatsCollectorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final int ISOLATED_UID = 99123; private static final int UID_1 = 42; private static final int UID_2 = 99; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java index 56362429e1f5..b89310f050b4 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.SparseLongArray; import androidx.test.filters.SmallTest; @@ -35,16 +34,11 @@ import org.junit.runner.RunWith; @SmallTest @SuppressWarnings("GuardedBy") public class CustomEnergyConsumerPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .initMeasuredEnergyStatsLocked(new String[]{"CUSTOM_COMPONENT1", "CUSTOM_COMPONENT2"}); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java index 757025ecc6f8..0d21349db7e6 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -35,16 +34,11 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class FlashlightPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java index 506bab4b3600..b7a0d3d50ddc 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -36,16 +35,12 @@ import org.junit.runner.RunWith; @SmallTest @SuppressWarnings("GuardedBy") public class GnssPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 222; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_GPS_ON, 360.0) .setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java index 487d86446a19..f9f2119b4762 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java @@ -19,7 +19,6 @@ package com.android.server.power.stats; import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -33,14 +32,9 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class IdlePowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CPU_IDLE, 720.0) .setAveragePower(PowerProfile.POWER_CPU_SUSPEND, 360.0); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java index 3a27188e2643..fc0ddeb85684 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java @@ -19,7 +19,6 @@ package com.android.server.power.stats; import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -33,14 +32,9 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class MemoryPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_MEMORY, new double[] {360.0, 720.0, 1080.0}); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java index eba820e95783..b95ff4c590fc 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java @@ -62,18 +62,13 @@ import java.util.List; @SmallTest @SuppressWarnings("GuardedBy") public class MobileRadioPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; @Mock NetworkStatsManager mNetworkStatsManager; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); @Test diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java index cd3683ba0ca8..645411cf628a 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java @@ -75,11 +75,6 @@ public class MobileRadioPowerStatsCollectorTest { private static final int ISOLATED_UID = 99123; @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule().setPowerStatsThrottlePeriodMillis( BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, 10000); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java index a04f7212204d..8e7e4371bd13 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java @@ -32,7 +32,6 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.PersistableBundle; import android.platform.test.annotations.DisabledOnRavenwood; -import android.platform.test.ravenwood.RavenwoodRule; import android.power.PowerStatsInternal; import androidx.test.filters.SmallTest; @@ -41,7 +40,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.os.PowerStats; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,11 +49,6 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @SmallTest public class PowerStatsCollectorTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private final MockClock mMockClock = new MockClock(); private final HandlerThread mHandlerThread = new HandlerThread("test"); private Handler mHandler; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java index 143d046add32..23787159d5de 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java @@ -18,11 +18,8 @@ package com.android.server.power.stats; import static com.google.common.truth.Truth.assertThat; -import android.platform.test.ravenwood.RavenwoodRule; - import androidx.test.runner.AndroidJUnit4; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,11 +30,6 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class PowerStatsSchedulerTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - @Test public void alignToWallClock() { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java index dc8d92032b57..064d999b35ec 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -29,7 +28,6 @@ import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.xmlpull.v1.XmlPullParser; @@ -45,11 +43,6 @@ import java.util.List; public class PowerStatsStoreTest { private static final long MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES = 2 * 1024; - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private PowerStatsStore mPowerStatsStore; private File mStoreDirectory; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java index 7f20035253f0..101c362fead4 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java @@ -25,7 +25,6 @@ import android.app.ActivityManager; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import android.view.Display; import androidx.test.filters.SmallTest; @@ -39,18 +38,13 @@ import org.junit.runner.RunWith; @SmallTest @SuppressWarnings("GuardedBy") public class ScreenPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 43; private static final long MINUTE_IN_MS = 60 * 1000; private static final long MINUTE_IN_US = 60 * 1000 * 1000; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, 0, 36.0) .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, 0, 48.0) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java index 8c09d1dbfc9d..c87f04d53af8 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java @@ -28,7 +28,6 @@ import android.hardware.power.stats.EnergyConsumerType; import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.Handler; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.Clock; import com.android.internal.os.PowerStats; @@ -47,11 +46,6 @@ public class ScreenPowerStatsCollectorTest { private static final int ISOLATED_UID = 99123; @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setPowerStatsThrottlePeriodMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, 1000); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java index c01f05f43c04..0a42170beffd 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java @@ -41,11 +41,6 @@ import java.util.List; @RunWith(AndroidJUnit4.class) @SmallTest public class SensorPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int SENSOR_HANDLE_1 = 1; @@ -53,7 +48,7 @@ public class SensorPowerCalculatorTest { private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); @Test @@ -93,7 +88,7 @@ public class SensorPowerCalculatorTest { } private Sensor createSensor(int handle, int type, float power) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { Sensor sensor = mock(Sensor.class); when(sensor.getHandle()).thenReturn(handle); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java index b9b710118cc7..e70f7df92981 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; import android.os.Process; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -35,16 +34,11 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class VideoPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_VIDEO, 360.0); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java index 9645e9088bbb..cfae6b19752d 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java @@ -43,7 +43,6 @@ public class WakelockPowerCalculatorTest { @Rule(order = 0) public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) .setSystemPropertyImmutable( "persist.sys.com.android.server.power.feature.flags." + "framework_wakelock_info-override", diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java index 827d2f8f04c8..0ec0575a20a1 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java @@ -54,11 +54,6 @@ import java.util.List; @SmallTest @SuppressWarnings("GuardedBy") public class WifiPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; @@ -66,7 +61,7 @@ public class WifiPowerCalculatorTest { @Mock NetworkStatsManager mNetworkStatsManager; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE, 360.0) .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX, 480.0) @@ -92,7 +87,7 @@ public class WifiPowerCalculatorTest { private NetworkStats buildNetworkStats(long elapsedRealtime, long rxBytes, long rxPackets, long txBytes, long txPackets) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { NetworkStats stats = mock(NetworkStats.class); // when(stats.getElapsedRealtime()).thenReturn(elapsedRealtime); @@ -358,7 +353,7 @@ public class WifiPowerCalculatorTest { private WifiActivityEnergyInfo buildWifiActivityEnergyInfo(long timeSinceBoot, int stackState, long txDuration, long rxDuration, long scanDuration, long idleDuration) { - if (RavenwoodRule.isUnderRavenwood()) { + if (RavenwoodRule.isOnRavenwood()) { WifiActivityEnergyInfo info = mock(WifiActivityEnergyInfo.class); when(info.getTimeSinceBootMillis()).thenReturn(timeSinceBoot); when(info.getStackState()).thenReturn(stackState); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java index a26b2c955380..3e15c0e2131e 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java @@ -68,11 +68,6 @@ public class WifiPowerStatsCollectorTest { private static final int ISOLATED_UID = 99123; @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setPowerStatsThrottlePeriodMillis(BatteryConsumer.POWER_COMPONENT_WIFI, 1000); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java index 58e9d1e26f2c..7ca3a9d42e80 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java @@ -31,7 +31,6 @@ import android.annotation.SuppressLint; import android.hardware.power.stats.EnergyConsumerType; import android.os.BatteryConsumer; import android.os.Handler; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.Clock; import com.android.internal.os.PowerProfile; @@ -52,11 +51,6 @@ import org.mockito.MockitoAnnotations; public class AmbientDisplayPowerStatsProcessorTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setNumDisplays(2) .setAveragePowerForOrdinal(PowerProfile.POWER_GROUP_DISPLAY_AMBIENT, 0, 180.0) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java index e6e7f6e105b7..10d5e800a799 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java @@ -35,7 +35,6 @@ import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.PersistableBundle; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.annotation.NonNull; @@ -44,17 +43,11 @@ import com.android.internal.os.PowerStats; import com.android.server.power.stats.MockClock; import com.android.server.power.stats.format.BinaryStatePowerStatsLayout; -import org.junit.Rule; import org.junit.Test; import java.util.function.Supplier; public class BinaryStatePowerStatsProcessorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java index 6d7119dc1f0e..d8328bf5b1e7 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java @@ -69,18 +69,13 @@ import java.util.function.Supplier; public class BluetoothPowerStatsProcessorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; private static final int BLUETOOTH_ENERGY_CONSUMER_ID = 1; private static final int VOLTAGE_MV = 3500; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX, 50.0) .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX, 100.0) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java index a95963242d8f..2244b734937f 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java @@ -40,7 +40,6 @@ import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.Handler; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.Clock; import com.android.internal.os.MonotonicClock; @@ -63,11 +62,6 @@ import java.util.function.Supplier; public class CameraPowerStatsTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CAMERA, 100.0) .initMeasuredEnergyStatsLocked(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java index dcddf06f01fb..3bc97bdaf7e1 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java @@ -33,7 +33,6 @@ import static org.junit.Assert.fail; import android.os.BatteryConsumer; import android.os.PersistableBundle; -import android.platform.test.ravenwood.RavenwoodRule; import android.util.IntArray; import android.util.LongArray; @@ -60,11 +59,6 @@ import java.util.Map; @SmallTest public class CpuPowerStatsProcessorTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720) .setCpuScalingPolicy(0, new int[]{0, 1}, new int[]{100, 200}) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java index a421675f1896..c18bc3e5befa 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java @@ -39,7 +39,6 @@ import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyConsumerType; import android.os.Handler; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.Clock; import com.android.internal.os.PowerStats; @@ -64,11 +63,6 @@ import java.util.function.Consumer; public class CustomEnergyConsumerPowerStatsTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); public static final int ENERGY_CONSUMER_ID1 = 77; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java index b4f21133f621..9071389c9004 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java @@ -41,7 +41,6 @@ import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.Handler; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.Clock; import com.android.internal.os.MonotonicClock; @@ -64,11 +63,6 @@ import java.util.function.Supplier; public class GnssPowerStatsTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_GPS_ON, 100.0) .setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, new double[]{1000, 100}) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java index 3dc401769e7d..95bf93139ef2 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java @@ -73,18 +73,13 @@ import java.util.function.LongSupplier; import java.util.function.Supplier; public class MobileRadioPowerStatsProcessorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; private static final int MOBILE_RADIO_ENERGY_CONSUMER_ID = 1; private static final int VOLTAGE_MV = 3500; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); @Mock private Context mContext; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java index 704ee62f764f..14dd975b5526 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java @@ -27,7 +27,6 @@ import static org.mockito.Mockito.verify; import android.os.ConditionVariable; import android.os.Handler; import android.os.HandlerThread; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.MonotonicClock; @@ -37,7 +36,6 @@ import com.android.server.power.stats.PowerStatsSpan; import com.android.server.power.stats.PowerStatsStore; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import java.io.IOException; @@ -52,11 +50,6 @@ import java.util.function.Consumer; public class MultiStatePowerAttributorTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private PowerStatsStore mPowerStatsStore; private Handler mHandler; private final MockClock mClock = new MockClock(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java index 2f742d74d8e6..742f250398cc 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java @@ -37,7 +37,6 @@ import android.net.NetworkStats; import android.os.BatteryConsumer; import android.os.Handler; import android.os.OutcomeReceiver; -import android.platform.test.ravenwood.RavenwoodRule; import android.telephony.ModemActivityInfo; import android.telephony.TelephonyManager; @@ -59,15 +58,10 @@ import java.util.function.LongSupplier; import java.util.function.Supplier; public class PhoneCallPowerStatsProcessorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int VOLTAGE_MV = 3500; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); @Mock private Context mContext; diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java index 9ef58cc28a69..a5a29f5883b1 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java @@ -33,7 +33,6 @@ import android.os.Message; import android.os.Parcel; import android.os.PersistableBundle; import android.os.UidBatteryConsumer; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.runner.AndroidJUnit4; @@ -67,11 +66,6 @@ public class PowerStatsExporterTest { private static final double TOLERANCE = 0.01; @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720) .setCpuScalingPolicy(0, new int[]{0}, new int[]{100}) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java index 31456a1574d0..1ca62b46b8e7 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java @@ -36,7 +36,6 @@ import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.Handler; import android.os.Process; -import android.platform.test.ravenwood.RavenwoodRule; import com.android.internal.os.Clock; import com.android.internal.os.PowerProfile; @@ -59,11 +58,6 @@ import java.util.function.Supplier; public class ScreenPowerStatsProcessorTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setNumDisplays(2) .setAveragePowerForOrdinal(PowerProfile.POWER_GROUP_DISPLAY_AMBIENT, 0, 180.0) diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java index c2f01d1fa65c..3c8a58095a60 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java @@ -58,11 +58,6 @@ import java.util.function.Supplier; public class SensorPowerStatsProcessorTest { @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - @Rule(order = 1) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .initMeasuredEnergyStatsLocked(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java index e36056a98c85..d4e6810c706d 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java @@ -74,18 +74,13 @@ import java.util.List; import java.util.function.Supplier; public class WifiPowerStatsProcessorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - private static final double PRECISION = 0.00001; private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101; private static final int WIFI_ENERGY_CONSUMER_ID = 1; private static final int VOLTAGE_MV = 3500; - @Rule(order = 1) + @Rule(order = 0) public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE, 360.0) .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX, 480.0) diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java index a0482382fb41..99c922ca30c4 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java @@ -75,12 +75,13 @@ public class AutoclickControllerTest { private static class MotionEventCaptor extends BaseEventStreamTransformation { public MotionEvent downEvent; - + public int eventCount = 0; @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downEvent = event; + eventCount++; break; } } @@ -922,6 +923,41 @@ public class AutoclickControllerTest { mController.onKeyEvent(keyEvent, /* policyFlags= */ 0); } + @Test + @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR) + public void sendClick_clickType_doubleclick_triggerClickTwice() { + MotionEventCaptor motionEventCaptor = new MotionEventCaptor(); + mController.setNext(motionEventCaptor); + + injectFakeMouseActionHoverMoveEvent(); + // Set delay to zero so click is scheduled to run immediately. + mController.mClickScheduler.updateDelay(0); + + // Set click type to double click. + mController.clickPanelController.handleAutoclickTypeChange( + AutoclickTypePanel.AUTOCLICK_TYPE_DOUBLE_CLICK); + AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class); + mController.mAutoclickTypePanel = mockAutoclickTypePanel; + + // Send hover move event. + MotionEvent hoverMove = MotionEvent.obtain( + /* downTime= */ 0, + /* eventTime= */ 100, + /* action= */ MotionEvent.ACTION_HOVER_MOVE, + /* x= */ 30f, + /* y= */ 0f, + /* metaState= */ 0); + hoverMove.setSource(InputDevice.SOURCE_MOUSE); + mController.onMotionEvent(hoverMove, hoverMove, /* policyFlags= */ 0); + mTestableLooper.processAllMessages(); + + // Verify left click sent. + assertThat(motionEventCaptor.downEvent).isNotNull(); + assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo( + MotionEvent.BUTTON_PRIMARY); + assertThat(motionEventCaptor.eventCount).isEqualTo(2); + } + private MotionEvent getFakeMotionHoverMoveEvent() { return MotionEvent.obtain( /* downTime= */ 0, diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java index 02361ff259c2..4c71f7e994b8 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java @@ -21,8 +21,12 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.times; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.never; import android.content.Context; import android.testing.AndroidTestingRunner; @@ -125,37 +129,107 @@ public class AutoclickScrollPanelTest { } @Test - public void directionButtons_onHover_callsHandleScroll() { - // Test up button. - triggerHoverEvent(mUpButton); - verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_UP); - - // Test down button. - triggerHoverEvent(mDownButton); - verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_DOWN); - - // Test left button. - triggerHoverEvent(mLeftButton); - verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_LEFT); - - // Test right button. - triggerHoverEvent(mRightButton); - verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_RIGHT); + public void directionButtons_hoverEvents_callsHoverButtonChange() { + // Test hover enter on direction button. + triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_ENTER); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_UP), eq(/* hovered= */ true)); + + // Test hover move. + reset(mMockScrollPanelController); + triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_MOVE); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_UP), eq(/* hovered= */ true)); + + // Test hover exit. + reset(mMockScrollPanelController); + triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_EXIT); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_UP), eq(/* hovered= */ false)); } @Test - public void exitButton_onHover_callsExitScrollMode() { - // Test exit button. - triggerHoverEvent(mExitButton); - verify(mMockScrollPanelController).exitScrollMode(); + public void exitButton_hoverEvents_callsHoverButtonChange() { + // Test hover enter on exit button. + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_ENTER); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ true)); + + // Test hover exit - should call the hover change method with false. + reset(mMockScrollPanelController); + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_EXIT); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ false)); + + // Test exit button hover move - should be ignored. + reset(mMockScrollPanelController); + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_MOVE); + verify(mMockScrollPanelController, never()).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_EXIT), anyBoolean()); + } + + @Test + public void hoverOnButtonSequence_handledCorrectly() { + // Test a realistic sequence of events. + // Case 1. Hover enter on up button, then hover move with in up button twice. + reset(mMockScrollPanelController); + triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_ENTER); + triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_MOVE); + triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_MOVE); + verify(mMockScrollPanelController, times(3)).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_UP), eq(true)); + + // Case 2. Move from left button to exit button. + reset(mMockScrollPanelController); + triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_ENTER); + triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_MOVE); + triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_EXIT); + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_MOVE); + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_ENTER); + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_EXIT); + + // Verify left button events - 2 'true' calls (enter+move) and 1 'false' call (exit). + verify(mMockScrollPanelController, times(2)).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_LEFT), eq(/* hovered= */ true)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_LEFT), eq(/* hovered= */ false)); + // Verify exit button events - hover_move is ignored so 1 'true' call (enter) and 1 + // 'false' call (exit). + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ true)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ false)); + + // Case 3. Quick transitions between buttons: left → right → down → exit + reset(mMockScrollPanelController); + triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_EXIT); + triggerHoverEvent(mRightButton, MotionEvent.ACTION_HOVER_ENTER); + triggerHoverEvent(mRightButton, MotionEvent.ACTION_HOVER_EXIT); + triggerHoverEvent(mDownButton, MotionEvent.ACTION_HOVER_ENTER); + triggerHoverEvent(mDownButton, MotionEvent.ACTION_HOVER_EXIT); + triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_ENTER); + + // Verify all hover enter/exit events were properly handled + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_LEFT), eq(/* hovered= */ false)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_RIGHT), eq(/* hovered= */ true)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_RIGHT), eq(/* hovered= */ false)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_DOWN), eq(/* hovered= */ true)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_DOWN), eq(/* hovered= */ false)); + verify(mMockScrollPanelController).onHoverButtonChange( + eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ true)); } // Helper method to simulate a hover event on a view. - private void triggerHoverEvent(View view) { + private void triggerHoverEvent(View view, int action) { MotionEvent event = MotionEvent.obtain( /* downTime= */ 0, /* eventTime= */ 0, - /* action= */ MotionEvent.ACTION_HOVER_ENTER, + /* action= */ action, /* x= */ 0, /* y= */ 0, /* metaState= */ 0); diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java index 67fc564fa778..2e07cd8ae698 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java @@ -22,18 +22,25 @@ import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.sensor.IVirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensor; +import android.companion.virtual.sensor.VirtualSensorAdditionalInfo; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorEvent; import android.content.AttributionSource; import android.hardware.Sensor; +import android.hardware.SensorAdditionalInfo; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -49,6 +56,7 @@ import com.google.common.collect.Iterables; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -65,6 +73,9 @@ public class SensorControllerTest { private static final int VIRTUAL_SENSOR_TYPE = Sensor.TYPE_ACCELEROMETER; + private static final float[] ADDITIONAL_INFO_VALUES_1 = new float[] {1.2f, 3.4f}; + private static final float[] ADDITIONAL_INFO_VALUES_2 = new float[] {5.6f, 7.8f}; + @Mock private SensorManagerInternal mSensorManagerInternalMock; @Mock @@ -155,6 +166,53 @@ public class SensorControllerTest { } @Test + public void sendSensorAdditionalInfo_invalidToken_throwsException() throws Exception { + SensorController sensorController = doCreateSensorSuccessfully(); + + final VirtualSensorAdditionalInfo info = + new VirtualSensorAdditionalInfo.Builder(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY) + .addValues(ADDITIONAL_INFO_VALUES_1) + .addValues(ADDITIONAL_INFO_VALUES_2) + .build(); + assertThrows( + IllegalArgumentException.class, + () -> sensorController.sendSensorAdditionalInfo( + new Binder("invalidSensorToken"), info)); + } + + @Test + public void sendSensorAdditionalInfo_success() throws Exception { + SensorController sensorController = doCreateSensorSuccessfully(); + + clearInvocations(mSensorManagerInternalMock); + when(mSensorManagerInternalMock.sendSensorAdditionalInfo( + anyInt(), anyInt(), anyInt(), anyLong(), any())) + .thenReturn(true); + IBinder token = Iterables.getOnlyElement(sensorController.getSensorDescriptors().keySet()); + + final VirtualSensorAdditionalInfo info = + new VirtualSensorAdditionalInfo.Builder(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY) + .addValues(ADDITIONAL_INFO_VALUES_1) + .addValues(ADDITIONAL_INFO_VALUES_2) + .build(); + sensorController.sendSensorAdditionalInfo(token, info); + + InOrder inOrder = inOrder(mSensorManagerInternalMock); + inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo( + eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_FRAME_BEGIN), + /*serial=*/ eq(0), /* timestamp= */ anyLong(), /*values=*/ isNull()); + inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo( + eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY), + /*serial=*/ eq(0), /* timestamp= */ anyLong(), eq(ADDITIONAL_INFO_VALUES_1)); + inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo( + eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY), + /*serial=*/ eq(1), /* timestamp= */ anyLong(), eq(ADDITIONAL_INFO_VALUES_2)); + inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo( + eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_FRAME_END), + /*serial=*/ eq(0), /* timestamp= */ anyLong(), /*values=*/ isNull()); + } + + @Test public void close_unregistersSensors() throws Exception { SensorController sensorController = doCreateSensorSuccessfully(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index aa1d5835bfc8..aacef3f0acaf 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -341,18 +341,9 @@ public class HdmiCecLocalDeviceTvTest { HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( ADDR_TV, ADDR_AUDIO_SYSTEM); - // <Report ARC Initiated> should only be sent after SAD querying is done - assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); - - // Finish querying SADs - for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); - mTestLooper.dispatchAll(); - } - assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); + // But we need to check SADs started to be queried at this time + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); mNativeWrapper.clearResultMessages(); } @@ -752,17 +743,6 @@ public class HdmiCecLocalDeviceTvTest { HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( ADDR_TV, ADDR_AUDIO_SYSTEM); - // <Report ARC Initiated> should only be sent after SAD querying is done - assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); - - // Finish querying SADs - for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); - mTestLooper.dispatchAll(); - } - assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); } @@ -1067,16 +1047,6 @@ public class HdmiCecLocalDeviceTvTest { HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( ADDR_TV, ADDR_AUDIO_SYSTEM); - // <Report ARC Initiated> should only be sent after SAD querying is done - assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); - // Finish querying SADs - for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); - mTestLooper.dispatchAll(); - } - assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); mNativeWrapper.clearResultMessages(); @@ -1268,16 +1238,6 @@ public class HdmiCecLocalDeviceTvTest { mNativeWrapper.onCecMessage(initiateArc); mTestLooper.dispatchAll(); - - // Finish querying SADs - for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); - mTestLooper.dispatchAll(); - } - - // ARC should be established after RequestSadAction is finished assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); @@ -1421,17 +1381,6 @@ public class HdmiCecLocalDeviceTvTest { HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( ADDR_TV, ADDR_AUDIO_SYSTEM); - // <Report ARC Initiated> should only be sent after SAD querying is done - assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); - - // Finish querying SADs - for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); - mTestLooper.dispatchAll(); - } - assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 2868e559e02f..125791acc61a 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -18,7 +18,6 @@ package com.android.server.locksettings; import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION; import static android.security.Flags.FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL; -import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; @@ -558,7 +557,6 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Test public void testVerifyCredential_notifyLockSettingsStateListeners_whenGoodPassword() throws Exception { - mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); final LockscreenCredential password = newPassword("password"); setCredential(PRIMARY_USER_ID, password); final LockSettingsStateListener listener = mock(LockSettingsStateListener.class); @@ -574,7 +572,6 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Test public void testVerifyCredential_notifyLockSettingsStateListeners_whenBadPassword() throws Exception { - mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); final LockscreenCredential password = newPassword("password"); setCredential(PRIMARY_USER_ID, password); final LockscreenCredential badPassword = newPassword("badPassword"); @@ -590,7 +587,6 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Test public void testLockSettingsStateListener_registeredThenUnregistered() throws Exception { - mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); final LockscreenCredential password = newPassword("password"); setCredential(PRIMARY_USER_ID, password); final LockscreenCredential badPassword = newPassword("badPassword"); diff --git a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java index c7a06b8eec7b..339bac4f768b 100644 --- a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java @@ -259,7 +259,7 @@ public class AdvancedProtectionServiceTest { AdvancedProtectionProvider provider = new AdvancedProtectionProvider() { @Override - public List<AdvancedProtectionFeature> getFeatures() { + public List<AdvancedProtectionFeature> getFeatures(Context context) { return List.of(feature2); } }; @@ -291,7 +291,7 @@ public class AdvancedProtectionServiceTest { AdvancedProtectionProvider provider = new AdvancedProtectionProvider() { @Override - public List<AdvancedProtectionFeature> getFeatures() { + public List<AdvancedProtectionFeature> getFeatures(Context context) { return List.of(feature2); } }; diff --git a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java index b76e0bc8cd14..c107bd4e62e8 100644 --- a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java @@ -18,7 +18,6 @@ package com.android.server.security.authenticationpolicy; import static android.adaptiveauth.Flags.FLAG_ENABLE_ADAPTIVE_AUTH; import static android.adaptiveauth.Flags.FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS; -import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS; import static android.security.authenticationpolicy.AuthenticationPolicyManager.ERROR_UNSUPPORTED; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST; @@ -112,7 +111,6 @@ public class AuthenticationPolicyServiceTest { MockitoAnnotations.initMocks(this); mSetFlagsRule.enableFlags(FLAG_ENABLE_ADAPTIVE_AUTH); - mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); mSetFlagsRule.enableFlags(FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS); mContext = spy(ApplicationProvider.getApplicationContext()); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index bc8b7becc919..902171d614d9 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -16844,22 +16844,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void updateAutomaticZenRule_implicitRuleWithoutCPS_disallowedFromApp() throws Exception { setUpRealZenTest(); mService.setCallerIsNormalPackage(); - assertThat(mBinderService.getAutomaticZenRules()).isEmpty(); + assertThat(mBinderService.getAutomaticZenRules().getList()).isEmpty(); // Create an implicit zen rule by calling setNotificationPolicy from an app. mBinderService.setNotificationPolicy(mPkg, new NotificationManager.Policy(0, 0, 0), false); - assertThat(mBinderService.getAutomaticZenRules()).hasSize(1); - Map.Entry<String, AutomaticZenRule> rule = getOnlyElement( - mBinderService.getAutomaticZenRules().entrySet()); - assertThat(rule.getValue().getOwner()).isNull(); - assertThat(rule.getValue().getConfigurationActivity()).isNull(); + assertThat(mBinderService.getAutomaticZenRules().getList()).hasSize(1); + AutomaticZenRule.AzrWithId rule = getOnlyElement( + (List<AutomaticZenRule.AzrWithId>) mBinderService.getAutomaticZenRules().getList()); + assertThat(rule.mRule.getOwner()).isNull(); + assertThat(rule.mRule.getConfigurationActivity()).isNull(); // Now try to update said rule (e.g. disable it). Should fail. // We also validate the exception message because NPE could be thrown by all sorts of test // issues (e.g. misconfigured mocks). - rule.getValue().setEnabled(false); + rule.mRule.setEnabled(false); NullPointerException e = assertThrows(NullPointerException.class, - () -> mBinderService.updateAutomaticZenRule(rule.getKey(), rule.getValue(), false)); + () -> mBinderService.updateAutomaticZenRule(rule.mId, rule.mRule, false)); assertThat(e.getMessage()).isEqualTo( "Rule must have a ConditionProviderService and/or configuration activity"); } @@ -16869,24 +16869,24 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void updateAutomaticZenRule_implicitRuleWithoutCPS_allowedFromSystem() throws Exception { setUpRealZenTest(); mService.setCallerIsNormalPackage(); - assertThat(mBinderService.getAutomaticZenRules()).isEmpty(); + assertThat(mBinderService.getAutomaticZenRules().getList()).isEmpty(); // Create an implicit zen rule by calling setNotificationPolicy from an app. mBinderService.setNotificationPolicy(mPkg, new NotificationManager.Policy(0, 0, 0), false); - assertThat(mBinderService.getAutomaticZenRules()).hasSize(1); - Map.Entry<String, AutomaticZenRule> rule = getOnlyElement( - mBinderService.getAutomaticZenRules().entrySet()); - assertThat(rule.getValue().getOwner()).isNull(); - assertThat(rule.getValue().getConfigurationActivity()).isNull(); + assertThat(mBinderService.getAutomaticZenRules().getList()).hasSize(1); + AutomaticZenRule.AzrWithId rule = getOnlyElement( + (List<AutomaticZenRule.AzrWithId>) mBinderService.getAutomaticZenRules().getList()); + assertThat(rule.mRule.getOwner()).isNull(); + assertThat(rule.mRule.getConfigurationActivity()).isNull(); // Now update said rule from Settings (e.g. disable it). Should work! mService.isSystemUid = true; - rule.getValue().setEnabled(false); - mBinderService.updateAutomaticZenRule(rule.getKey(), rule.getValue(), false); + rule.mRule.setEnabled(false); + mBinderService.updateAutomaticZenRule(rule.mId, rule.mRule, false); - Map.Entry<String, AutomaticZenRule> updatedRule = getOnlyElement( - mBinderService.getAutomaticZenRules().entrySet()); - assertThat(updatedRule.getValue().isEnabled()).isFalse(); + AutomaticZenRule.AzrWithId updatedRule = getOnlyElement( + (List<AutomaticZenRule.AzrWithId>) mBinderService.getAutomaticZenRules().getList()); + assertThat(updatedRule.mRule.isEnabled()).isFalse(); } @Test diff --git a/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java b/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java index 9e59bced01f1..4ecf6abf7860 100644 --- a/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java @@ -145,8 +145,8 @@ public final class WindowWakeUpPolicyTests { // Verify the policy wake up call succeeds because of the call on the delegate, and not // because of a PowerManager wake up. assertThat(mPolicy.wakeUpFromMotion( - mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true)).isTrue(); - verify(mInputWakeUpDelegate).wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true); + mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true, false)).isTrue(); + verify(mInputWakeUpDelegate).wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true, false); verifyNoPowerManagerWakeUp(); setDelegatedMotionWakeUpResult(false); @@ -154,8 +154,8 @@ public final class WindowWakeUpPolicyTests { // Verify the policy wake up call succeeds because of the PowerManager wake up, since the // delegate would not handle the wake up request. assertThat(mPolicy.wakeUpFromMotion( - mDefaultDisplay.getDisplayId(), 300, SOURCE_ROTARY_ENCODER, false)).isTrue(); - verify(mInputWakeUpDelegate).wakeUpFromMotion(300, SOURCE_ROTARY_ENCODER, false); + mDefaultDisplay.getDisplayId(), 300, SOURCE_ROTARY_ENCODER, false, false)).isTrue(); + verify(mInputWakeUpDelegate).wakeUpFromMotion(300, SOURCE_ROTARY_ENCODER, false, false); verify(mPowerManager).wakeUp(300, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION"); } @@ -214,8 +214,9 @@ public final class WindowWakeUpPolicyTests { // Check that the wake up does not happen because the theater mode policy check fails. assertThat(mPolicy.wakeUpFromMotion( - mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true)).isFalse(); - verify(mInputWakeUpDelegate, never()).wakeUpFromMotion(anyLong(), anyInt(), anyBoolean()); + mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true, false)).isFalse(); + verify(mInputWakeUpDelegate, never()) + .wakeUpFromMotion(anyLong(), anyInt(), anyBoolean(), anyBoolean()); } @Test @@ -227,7 +228,8 @@ public final class WindowWakeUpPolicyTests { setBooleanRes(config_allowTheaterModeWakeFromMotion, false); mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock); - mPolicy.wakeUpFromMotion(mDefaultDisplay.getDisplayId(), 200L, SOURCE_TOUCHSCREEN, true); + mPolicy.wakeUpFromMotion( + mDefaultDisplay.getDisplayId(), 200L, SOURCE_TOUCHSCREEN, true, false); verify(mPowerManager).wakeUp(200L, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION"); } @@ -237,7 +239,7 @@ public final class WindowWakeUpPolicyTests { public void testWakeUpFromMotion() { runPowerManagerUpChecks( () -> mPolicy.wakeUpFromMotion(mDefaultDisplay.getDisplayId(), - mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, true), + mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, true, false), config_allowTheaterModeWakeFromMotion, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION"); @@ -251,7 +253,8 @@ public final class WindowWakeUpPolicyTests { mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock); boolean displayWokeUp = mPolicy.wakeUpFromMotion( - displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true); + displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true, + /* deviceGoingToSleep= */ false); // Verify that display is woken up assertThat(displayWokeUp).isTrue(); @@ -267,7 +270,8 @@ public final class WindowWakeUpPolicyTests { mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock); boolean displayWokeUp = mPolicy.wakeUpFromMotion( - displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true); + displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true, + /* deviceGoingToSleep= */ false); // Verify that power is woken up and display isn't woken up individually assertThat(displayWokeUp).isTrue(); @@ -442,7 +446,7 @@ public final class WindowWakeUpPolicyTests { } private void setDelegatedMotionWakeUpResult(boolean result) { - when(mInputWakeUpDelegate.wakeUpFromMotion(anyLong(), anyInt(), anyBoolean())) + when(mInputWakeUpDelegate.wakeUpFromMotion(anyLong(), anyInt(), anyBoolean(), anyBoolean())) .thenReturn(result); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java index eb6d5cf8bb14..aa794b2d071d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java @@ -19,10 +19,15 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; +import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; +import static com.android.server.wm.WindowStateAnimator.NO_SURFACE; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -244,4 +249,52 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { verify(displayWindowInsetsController, times(1)).setImeInputTargetRequestedVisibility( eq(true), any()); } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) + public void testOnPostLayout_resetServerVisibilityWhenImeIsNotDrawn() { + final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build(); + final WindowState inputTarget = newWindowBuilder("app", TYPE_APPLICATION).build(); + makeWindowVisibleAndDrawn(ime); + mImeProvider.setWindowContainer(ime, null, null); + mImeProvider.setServerVisible(true); + mImeProvider.setClientVisible(true); + mImeProvider.updateVisibility(); + mImeProvider.updateControlForTarget(inputTarget, true /* force */, null /* statsToken */); + + // Calling onPostLayout, as the drawn state is initially false. + mImeProvider.onPostLayout(); + assertTrue(mImeProvider.isSurfaceVisible()); + + // Reset window's drawn state + ime.mWinAnimator.mDrawState = NO_SURFACE; + mImeProvider.onPostLayout(); + assertFalse(mImeProvider.isServerVisible()); + assertFalse(mImeProvider.isSurfaceVisible()); + + // Set it back to drawn + ime.mWinAnimator.mDrawState = HAS_DRAWN; + mImeProvider.onPostLayout(); + assertTrue(mImeProvider.isServerVisible()); + assertTrue(mImeProvider.isSurfaceVisible()); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER) + public void testUpdateControlForTarget_differentControlTarget() throws RemoteException { + final WindowState oldTarget = newWindowBuilder("app", TYPE_APPLICATION).build(); + final WindowState newTarget = newWindowBuilder("newapp", TYPE_APPLICATION).build(); + + oldTarget.setRequestedVisibleTypes( + WindowInsets.Type.defaultVisible() | WindowInsets.Type.ime()); + mDisplayContent.setImeControlTarget(oldTarget); + mDisplayContent.setImeInputTarget(newTarget); + + // Having a null windowContainer will early return in updateControlForTarget + mImeProvider.setWindowContainer(null, null, null); + + clearInvocations(mDisplayContent); + mImeProvider.updateControlForTarget(newTarget, false /* force */, ImeTracker.Token.empty()); + verify(mDisplayContent, never()).getImeInputTarget(); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java index d3f3269392d8..0101c3cd630d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java @@ -284,7 +284,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE); assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE); - overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars()); + overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars(), null /* statsToken */); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); assertTrue(mPolicy.updateFrameRateVote(overrideWindow)); assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote); @@ -304,7 +304,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE); assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE); - overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars()); + overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars(), null /* statsToken */); assertEquals(0, mPolicy.getPreferredModeId(overrideWindow)); assertTrue(mPolicy.updateFrameRateVote(overrideWindow)); assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote); 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 71e84c0f1821..73102c4478d8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -1147,7 +1147,8 @@ public class WindowManagerServiceTests extends WindowTestsBase { argThat(h -> (h.inputConfig & InputConfig.SPY) == 0)); assertThrows(IllegalArgumentException.class, () -> - mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl, + mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */, + DEFAULT_DISPLAY, surfaceControl, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY, null /* region */)); } @@ -1217,7 +1218,8 @@ public class WindowManagerServiceTests extends WindowTestsBase { eq(surfaceControl), argThat(h -> (h.inputConfig & InputConfig.SPY) == 0)); - mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl, + mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */, + DEFAULT_DISPLAY, surfaceControl, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY, null /* region */); verify(mTransaction).setInputWindowInfo( @@ -1244,7 +1246,8 @@ public class WindowManagerServiceTests extends WindowTestsBase { eq(surfaceControl), argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_PRIVACY) == 0)); - mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl, + mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */, + DEFAULT_DISPLAY, surfaceControl, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SENSITIVE_FOR_PRIVACY, null /* region */); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 9dc70266bf3d..5347f9a36652 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -382,12 +382,17 @@ public class WindowProcessControllerTests extends WindowTestsBase { assertFalse(tracker.hasResumedActivity(mWpc.mUid)); assertTrue(mWpc.hasForegroundActivities()); - activity.setVisibility(false); activity.setVisibleRequested(false); - activity.setState(STOPPED, "test"); - + if (com.android.window.flags.Flags.useVisibleRequestedForProcessTracker()) { + assertTrue("PAUSING is visible", mWpc.hasVisibleActivities()); + activity.setState(PAUSED, "test"); + } else { + activity.setVisible(false); + } verify(tracker).onAllActivitiesInvisible(mWpc); assertFalse(mWpc.hasVisibleActivities()); + + activity.setState(STOPPED, "test"); assertFalse(mWpc.hasForegroundActivities()); } diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 9e57fd3c1a7b..c244168c65fd 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.content.Intent; import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.BadParcelableException; @@ -1174,6 +1175,10 @@ public final class Call { int callerNumberVerificationStatus, Uri contactPhotoUri, UserHandle originatingUser) { + if (extras == null) { + extras = new Bundle(); + } + extras.putParcelable(Intent.EXTRA_USER_HANDLE, originatingUser); mState = state; mTelecomCallId = telecomCallId; mHandle = handle; diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java index bd004e5e6231..07278e70f46e 100644 --- a/telecomm/java/android/telecom/ParcelableCall.java +++ b/telecomm/java/android/telecom/ParcelableCall.java @@ -19,7 +19,6 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; -import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -687,9 +686,6 @@ public final class ParcelableCall implements Parcelable { source.readList(conferenceableCallIds, classLoader, java.lang.String.class); Bundle intentExtras = source.readBundle(classLoader); Bundle extras = source.readBundle(classLoader); - if (extras == null) { - extras = new Bundle(); - } int supportedAudioRoutes = source.readInt(); boolean isRttCallChanged = source.readByte() == 1; ParcelableRttCall rttCall = source.readParcelable(classLoader, android.telecom.ParcelableRttCall.class); @@ -700,7 +696,6 @@ public final class ParcelableCall implements Parcelable { String activeChildCallId = source.readString(); Uri contactPhotoUri = source.readParcelable(classLoader, Uri.class); UserHandle associatedUser = source.readParcelable(classLoader, UserHandle.class); - extras.putParcelable(Intent.EXTRA_USER_HANDLE, associatedUser); return new ParcelableCallBuilder() .setId(id) .setState(state) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 50c5a6b68c7b..14915109999c 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3918,6 +3918,22 @@ public class CarrierConfigManager { "5g_icon_display_secondary_grace_period_string"; /** + * When an NR advanced connection is lost and a Physical Cell ID (PCI) change occurs within + * the primary timer{@link #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING}, delay updating the network + * icon. + * + * <p>This delay is implemented because a rapid PCI change often indicates the device is + * switching to a nearby cell tower to quickly restore the NR advanced connection. Displaying + * an intermediate network icon (like 4G/LTE) might be misleading if the 5G connection is + * restored shortly after. This value sets the delay in seconds; 0 disables the feature.</p> + * + * @hide + */ + public static final String KEY_NR_ADVANCED_PCI_CHANGE_SECONDARY_TIMER_SECONDS_INT = + "nr_advanced_pci_change_secondary_timer_seconds_int"; + + + /** * The secondary grace periods in seconds to use if NR advanced icon was shown due to connecting * to bands specified in {@link #KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY}. * @@ -11222,6 +11238,7 @@ public class CarrierConfigManager { + "not_restricted_rrc_con:5G"); sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, ""); sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, ""); + sDefaults.putInt(KEY_NR_ADVANCED_PCI_CHANGE_SECONDARY_TIMER_SECONDS_INT, 0); sDefaults.putInt(KEY_NR_ADVANCED_BANDS_SECONDARY_TIMER_SECONDS_INT, 0); sDefaults.putBoolean(KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL, false); sDefaults.putBoolean(KEY_NR_TIMERS_RESET_ON_VOICE_QOS_BOOL, false); diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index f5282639ae6c..6e23edf936c7 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -614,7 +614,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** @hide */ public static int convertRssiAsuToDBm(int rssiAsu) { - if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) { + if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN || rssiAsu == Integer.MAX_VALUE) { return CellInfo.UNAVAILABLE; } if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index e6515f13b858..850ce3e2bbdc 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -16,7 +16,6 @@ package android.telephony; -import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -39,7 +38,6 @@ import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.Qos; -import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.TelephonyUtils; import java.lang.annotation.Retention; @@ -89,35 +87,30 @@ public final class PreciseDataConnectionState implements Parcelable { * Unsupported. The unsupported state is used when the data network cannot support the network * validation function for the current data connection state. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; /** * Not Requested. The not requested status is used when the data network supports the network * validation function, but no network validation is being performed yet. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; /** * In progress. The in progress state is used when the network validation process for the data * network is in progress. This state is followed by either success or failure. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; /** * Success. The Success status is used when network validation has been completed for the data * network and the result is successful. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_SUCCESS = 3; /** * Failure. The Failure status is used when network validation has been completed for the data * network and the result is failure. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public static final int NETWORK_VALIDATION_FAILURE = 4; /** @@ -360,7 +353,6 @@ public final class PreciseDataConnectionState implements Parcelable { * * @return the network validation status of the data call */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NetworkValidationStatus int getNetworkValidationStatus() { return mNetworkValidationStatus; } @@ -615,7 +607,6 @@ public final class PreciseDataConnectionState implements Parcelable { * @param networkValidationStatus the network validation status of the data call * @return The builder */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NonNull Builder setNetworkValidationStatus( @NetworkValidationStatus int networkValidationStatus) { mNetworkValidationStatus = networkValidationStatus; diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 2983e4442a78..7b2e6c2013cf 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -15347,11 +15347,15 @@ public class TelephonyManager { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. * @hide */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) @SystemApi public void notifyOtaEmergencyNumberDbInstalled() { try { @@ -15376,11 +15380,15 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} * * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. * @hide */ @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) @SystemApi public void updateOtaEmergencyNumberDbFilePath( @NonNull ParcelFileDescriptor otaParcelFileDescriptor) { @@ -15404,11 +15412,15 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} * * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. * @hide */ @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) @SystemApi public void resetOtaEmergencyNumberDbFilePath() { try { @@ -15490,11 +15502,15 @@ public class TelephonyManager { * or throw a SecurityException if the caller does not have the permission. * * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @NonNull - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList() { Map<Integer, List<EmergencyNumber>> emergencyNumberList = new HashMap<>(); try { @@ -15548,11 +15564,15 @@ public class TelephonyManager { * or throw a SecurityException if the caller does not have the permission. * @throws IllegalStateException if the Telephony process is not currently available. * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @NonNull - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList( @EmergencyServiceCategories int categories) { Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>(); @@ -15618,9 +15638,13 @@ public class TelephonyManager { * SIM card(s), Android database, modem, network or defaults; {@code false} otherwise. * @throws IllegalStateException if the Telephony process is not currently available. * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. */ - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) public boolean isEmergencyNumber(@NonNull String number) { try { ITelephony telephony = getITelephony(); @@ -15657,7 +15681,8 @@ public class TelephonyManager { * have the required permission/privileges * @throws IllegalStateException if the Telephony process is not currently available. * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. * * @deprecated Please use {@link TelephonyManager#isEmergencyNumber(String)} instead. * @hide @@ -15665,7 +15690,10 @@ public class TelephonyManager { @Deprecated @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) public boolean isPotentialEmergencyNumber(@NonNull String number) { try { ITelephony telephony = getITelephony(); @@ -15685,15 +15713,19 @@ public class TelephonyManager { * Returns the emergency number database version. * * <p>Requires Permission: - * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} * * @throws UnsupportedOperationException If the device does not have - * {@link PackageManager#FEATURE_TELEPHONY_CALLING}. + * {@link PackageManager#FEATURE_TELEPHONY_CALLING} or + * {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING) + @RequiresFeature(anyOf = { + PackageManager.FEATURE_TELEPHONY_CALLING, + PackageManager.FEATURE_TELEPHONY_MESSAGING + }) public int getEmergencyNumberDbVersion() { try { ITelephony telephony = getITelephony(); diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index b6f9e1f4c3af..0e7030688c70 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -17,7 +17,6 @@ package android.telephony.data; -import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -32,7 +31,6 @@ import android.telephony.PreciseDataConnectionState; import android.telephony.data.ApnSetting.ProtocolType; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.telephony.flags.Flags; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; @@ -455,7 +453,6 @@ public final class DataCallResponse implements Parcelable { * * @return The network validation status of data connection. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @PreciseDataConnectionState.NetworkValidationStatus int getNetworkValidationStatus() { return mNetworkValidationStatus; } @@ -936,7 +933,6 @@ public final class DataCallResponse implements Parcelable { * @param status The network validation status. * @return The same instance of the builder. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public @NonNull Builder setNetworkValidationStatus( @PreciseDataConnectionState.NetworkValidationStatus int status) { mNetworkValidationStatus = status; diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index f04e1c9b221d..5baf46388fc4 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -17,7 +17,6 @@ package android.telephony.data; import android.annotation.CallbackExecutor; -import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -40,7 +39,6 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IIntegerConsumer; -import com.android.internal.telephony.flags.Flags; import com.android.internal.util.FunctionalUtils; import com.android.telephony.Rlog; @@ -414,7 +412,6 @@ public abstract class DataService extends Service { * @param resultCodeCallback Listener for the {@link DataServiceCallback.ResultCode} that * request validation to the DataService and checks if the request has been submitted. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public void requestNetworkValidation(int cid, @NonNull @CallbackExecutor Executor executor, @NonNull @DataServiceCallback.ResultCode Consumer<Integer> resultCodeCallback) { diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java index f775de6ebef4..c42b29c143aa 100644 --- a/telephony/java/android/telephony/data/QualifiedNetworksService.java +++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java @@ -17,7 +17,6 @@ package android.telephony.data; import android.annotation.CallbackExecutor; -import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.SystemApi; import android.app.Service; @@ -41,7 +40,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IIntegerConsumer; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.flags.FeatureFlagsImpl; -import com.android.internal.telephony.flags.Flags; import com.android.internal.util.FunctionalUtils; import com.android.telephony.Rlog; @@ -290,7 +288,6 @@ public abstract class QualifiedNetworksService extends Service { * @param resultCodeCallback A callback to determine whether the request was successfully * submitted or not. */ - @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) public void requestNetworkValidation( @NetCapability int networkCapability, @NonNull @CallbackExecutor Executor executor, @@ -298,15 +295,6 @@ public abstract class QualifiedNetworksService extends Service { Objects.requireNonNull(executor, "executor cannot be null"); Objects.requireNonNull(resultCodeCallback, "resultCodeCallback cannot be null"); - if (!sFeatureFlag.networkValidation()) { - loge("networkValidation feature is disabled"); - executor.execute( - () -> - resultCodeCallback.accept( - DataServiceCallback.RESULT_ERROR_UNSUPPORTED)); - return; - } - IIntegerConsumer callback = new IIntegerConsumer.Stub() { @Override public void accept(int result) { diff --git a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java index 1b0279273dc7..b1d6e96dca9b 100644 --- a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java +++ b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java @@ -18,11 +18,7 @@ package com.android.fsverity; import static com.google.common.truth.Truth.assertThat; -import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.annotations.RootPermissionTest; -import android.platform.test.flag.junit.CheckFlagsRule; -import android.platform.test.flag.junit.host.HostFlagsValueProvider; -import android.security.Flags; import com.android.blockdevicewriter.BlockDeviceWriter; import com.android.tradefed.device.DeviceNotAvailableException; @@ -31,7 +27,6 @@ import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.testtype.junit4.DeviceTestRunOptions; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,16 +43,11 @@ import org.junit.runner.RunWith; */ @RootPermissionTest @RunWith(DeviceJUnit4ClassRunner.class) -@RequiresFlagsEnabled(Flags.FLAG_FSVERITY_API) public class FsVerityHostTest extends BaseHostJUnit4Test { private static final String TARGET_PACKAGE = "com.android.fsverity"; private static final String BASENAME = "test.file"; - @Rule - public final CheckFlagsRule mCheckFlagsRule = - HostFlagsValueProvider.createCheckFlagsRule(this::getDevice); - @Test public void testFsVeritySmallFile() throws Exception { prepareTest(10000); |