diff options
71 files changed, 937 insertions, 205 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index ed80ddbd2cd7..9f529548833d 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -256,6 +256,7 @@ public class AlarmManagerService extends SystemService { AlarmHandler mHandler; AppWakeupHistory mAppWakeupHistory; AppWakeupHistory mAllowWhileIdleHistory; + AppWakeupHistory mAllowWhileIdleCompatHistory; private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray(); private final SparseArray<RingBuffer<RemovedAlarm>> mRemovalHistory = new SparseArray<>(); ClockReceiver mClockReceiver; @@ -1633,6 +1634,7 @@ public class AlarmManagerService extends SystemService { mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR); + mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR); mNextWakeup = mNextNonWakeup = 0; @@ -2142,20 +2144,23 @@ public class AlarmManagerService extends SystemService { final int userId = UserHandle.getUserId(alarm.creatorUid); final int quota; final long window; + final AppWakeupHistory history; if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) { quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_WINDOW; + history = mAllowWhileIdleHistory; } else { quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + history = mAllowWhileIdleCompatHistory; } - final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow( + final int dispatchesInHistory = history.getTotalWakeupsInWindow( alarm.sourcePackage, userId); - if (dispatchesInWindow < quota) { + if (dispatchesInHistory < quota) { // fine to go out immediately. batterySaverPolicyElapsed = nowElapsed; } else { - batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage( + batterySaverPolicyElapsed = history.getNthLastWakeupForPackage( alarm.sourcePackage, userId, quota) + window; } } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) { @@ -2201,20 +2206,23 @@ public class AlarmManagerService extends SystemService { final int userId = UserHandle.getUserId(alarm.creatorUid); final int quota; final long window; + final AppWakeupHistory history; if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) { quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_WINDOW; + history = mAllowWhileIdleHistory; } else { quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + history = mAllowWhileIdleCompatHistory; } - final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow( + final int dispatchesInHistory = history.getTotalWakeupsInWindow( alarm.sourcePackage, userId); - if (dispatchesInWindow < quota) { + if (dispatchesInHistory < quota) { // fine to go out immediately. deviceIdlePolicyTime = nowElapsed; } else { - final long whenInQuota = mAllowWhileIdleHistory.getNthLastWakeupForPackage( + final long whenInQuota = history.getNthLastWakeupForPackage( alarm.sourcePackage, userId, quota) + window; deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed()); } @@ -2502,6 +2510,7 @@ public class AlarmManagerService extends SystemService { Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized"); // The API doesn't allow using both together. flags &= ~FLAG_ALLOW_WHILE_IDLE; + // Prioritized alarms don't need any extra permission to be exact. } else if (exact || allowWhileIdle) { final boolean needsPermission; boolean lowerQuota; @@ -2992,6 +3001,10 @@ public class AlarmManagerService extends SystemService { mAllowWhileIdleHistory.dump(pw, nowELAPSED); pw.println(); + pw.println("Allow while idle compat history:"); + mAllowWhileIdleCompatHistory.dump(pw, nowELAPSED); + pw.println(); + if (mLastPriorityAlarmDispatch.size() > 0) { pw.println("Last priority alarm dispatches:"); pw.increaseIndent(); @@ -4553,6 +4566,7 @@ public class AlarmManagerService extends SystemService { removeUserLocked(userHandle); mAppWakeupHistory.removeForUser(userHandle); mAllowWhileIdleHistory.removeForUser(userHandle); + mAllowWhileIdleCompatHistory.removeForUser(userHandle); } return; case Intent.ACTION_UID_REMOVED: @@ -4588,6 +4602,8 @@ public class AlarmManagerService extends SystemService { // package-removed and package-restarted case mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); mAllowWhileIdleHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); + mAllowWhileIdleCompatHistory.removeForPackage(pkg, + UserHandle.getUserId(uid)); removeLocked(uid, REMOVE_REASON_UNDEFINED); } else { // external-applications-unavailable case @@ -4965,7 +4981,10 @@ public class AlarmManagerService extends SystemService { if (isAllowedWhileIdleRestricted(alarm)) { // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm while the // device was in doze or battery saver. - mAllowWhileIdleHistory.recordAlarmForPackage(alarm.sourcePackage, + final AppWakeupHistory history = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) + ? mAllowWhileIdleHistory + : mAllowWhileIdleCompatHistory; + history.recordAlarmForPackage(alarm.sourcePackage, UserHandle.getUserId(alarm.creatorUid), nowELAPSED); mAlarmStore.updateAlarmDeliveries(a -> { if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) { diff --git a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java index 3069db32c548..6d67ee37d8e6 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java +++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java @@ -59,7 +59,7 @@ public class ThermalStatusRestriction extends JobRestriction { @Override public boolean isJobRestricted(JobStatus job) { - return mIsThermalRestricted && job.hasConnectivityConstraint(); + return mIsThermalRestricted; } @Override diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java index 35d00f03de67..9309c5b0d8e3 100644 --- a/core/java/android/hardware/location/ContextHubClientCallback.java +++ b/core/java/android/hardware/location/ContextHubClientCallback.java @@ -68,8 +68,11 @@ public class ContextHubClientCallback { /** * Callback invoked when a nanoapp is dynamically loaded at the attached Context Hub through - * the {@link android.hardware.location.ContextHubManager}. This callback is not invoked for a - * nanoapp that is loaded internally by CHRE (e.g. nanoapps that are preloaded by the system). + * the {@link android.hardware.location.ContextHubManager}. + * + * NOTE: This callback is <b>not</b> invoked for a nanoapp that is loaded internally by CHRE + * (e.g. nanoapps that are preloaded by the system). To check the availability of these + * nanoapps, use the {@link ContextHubManager#queryNanoApps(ContextHubInfo)} API. * * @param client the client that is associated with this callback * @param nanoAppId the ID of the nanoapp that had been loaded diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java index f69a7d7e5f16..9af0e09ee97a 100644 --- a/core/java/android/hardware/location/ContextHubManager.java +++ b/core/java/android/hardware/location/ContextHubManager.java @@ -128,7 +128,8 @@ public final class ContextHubManager { public static final int AUTHORIZATION_GRANTED = 2; /** - * Constants describing the type of events from a Context Hub. + * Constants describing the type of events from a Context Hub, as defined in + * {@link ContextHubClientCallback}. * {@hide} */ @Retention(RetentionPolicy.SOURCE) diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index a5b7e995293a..6bf394dc347b 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -441,23 +441,30 @@ public class Build { public static final int CUR_DEVELOPMENT = 10000; /** - * October 2008: The original, first, version of Android. Yay! + * The original, first, version of Android. Yay! + * + * <p>Released publicly as Android 1.0 in September 2008. */ public static final int BASE = 1; /** - * February 2009: First Android update, officially called 1.1. + * First Android update. + * + * <p>Released publicly as Android 1.1 in February 2009. */ public static final int BASE_1_1 = 2; /** - * May 2009: Android 1.5. + * C. + * + * <p>Released publicly as Android 1.5 in April 2009. */ public static final int CUPCAKE = 3; /** - * September 2009: Android 1.6. + * D. * + * <p>Released publicly as Android 1.6 in September 2009. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -481,8 +488,9 @@ public class Build { public static final int DONUT = 4; /** - * November 2009: Android 2.0 + * E. * + * <p>Released publicly as Android 2.0 in October 2009. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -501,23 +509,30 @@ public class Build { public static final int ECLAIR = 5; /** - * December 2009: Android 2.0.1 + * E incremental update. + * + * <p>Released publicly as Android 2.0.1 in December 2009. */ public static final int ECLAIR_0_1 = 6; /** - * January 2010: Android 2.1 + * E MR1. + * + * <p>Released publicly as Android 2.1 in January 2010. */ public static final int ECLAIR_MR1 = 7; /** - * June 2010: Android 2.2 + * F. + * + * <p>Released publicly as Android 2.2 in May 2010. */ public static final int FROYO = 8; /** - * November 2010: Android 2.3 + * G. * + * <p>Released publicly as Android 2.3 in December 2010. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -528,13 +543,16 @@ public class Build { public static final int GINGERBREAD = 9; /** - * February 2011: Android 2.3.3. + * G MR1. + * + * <p>Released publicly as Android 2.3.3 in February 2011. */ public static final int GINGERBREAD_MR1 = 10; /** - * February 2011: Android 3.0. + * H. * + * <p>Released publicly as Android 3.0 in February 2011. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -573,13 +591,16 @@ public class Build { public static final int HONEYCOMB = 11; /** - * May 2011: Android 3.1. + * H MR1. + * + * <p>Released publicly as Android 3.1 in May 2011. */ public static final int HONEYCOMB_MR1 = 12; /** - * June 2011: Android 3.2. + * H MR2. * + * <p>Released publicly as Android 3.2 in July 2011. * <p>Update to Honeycomb MR1 to support 7 inch tablets, improve * screen compatibility mode, etc.</p> * @@ -626,8 +647,9 @@ public class Build { public static final int HONEYCOMB_MR2 = 13; /** - * October 2011: Android 4.0. + * I. * + * <p>Released publicly as Android 4.0 in October 2011. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -672,13 +694,16 @@ public class Build { public static final int ICE_CREAM_SANDWICH = 14; /** - * December 2011: Android 4.0.3. + * I MR1. + * + * <p>Released publicly as Android 4.03 in December 2011. */ public static final int ICE_CREAM_SANDWICH_MR1 = 15; /** - * June 2012: Android 4.1. + * J. * + * <p>Released publicly as Android 4.1 in July 2012. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -720,8 +745,9 @@ public class Build { public static final int JELLY_BEAN = 16; /** - * November 2012: Android 4.2, Moar jelly beans! + * J MR1. * + * <p>Released publicly as Android 4.2 in November 2012. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -740,13 +766,16 @@ public class Build { public static final int JELLY_BEAN_MR1 = 17; /** - * July 2013: Android 4.3, the revenge of the beans. + * J MR2. + * + * <p>Released publicly as Android 4.3 in July 2013. */ public static final int JELLY_BEAN_MR2 = 18; /** - * October 2013: Android 4.4, KitKat, another tasty treat. + * K. * + * <p>Released publicly as Android 4.4 in October 2013. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see the * <a href="/about/versions/kitkat/">Android KitKat overview</a>.</p> @@ -778,8 +807,9 @@ public class Build { public static final int KITKAT = 19; /** - * June 2014: Android 4.4W. KitKat for watches, snacks on the run. + * K for watches. * + * <p>Released publicly as Android 4.4W in June 2014. * <p>Applications targeting this or a later release will get these * new changes in behavior:</p> * <ul> @@ -796,8 +826,9 @@ public class Build { public static final int L = 21; /** - * November 2014: Lollipop. A flat one with beautiful shadows. But still tasty. + * L. * + * <p>Released publicly as Android 5.0 in November 2014. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see the * <a href="/about/versions/lollipop/">Android Lollipop overview</a>.</p> @@ -828,15 +859,18 @@ public class Build { public static final int LOLLIPOP = 21; /** - * March 2015: Lollipop with an extra sugar coating on the outside! - * For more information about this release, see the + * L MR1. + * + * <p>Released publicly as Android 5.1 in March 2015. + * <p>For more information about this release, see the * <a href="/about/versions/android-5.1">Android 5.1 APIs</a>. */ public static final int LOLLIPOP_MR1 = 22; /** - * M is for Marshmallow! + * M. * + * <p>Released publicly as Android 6.0 in October 2015. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see the * <a href="/about/versions/marshmallow/">Android 6.0 Marshmallow overview</a>.</p> @@ -867,8 +901,9 @@ public class Build { public static final int M = 23; /** - * N is for Nougat. + * N. * + * <p>Released publicly as Android 7.0 in August 2016. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see * the <a href="/about/versions/nougat/">Android Nougat overview</a>.</p> @@ -921,7 +956,10 @@ public class Build { public static final int N = 24; /** - * N MR1: Nougat++. For more information about this release, see + * N MR1. + * + * <p>Released publicly as Android 7.1 in October 2016. + * <p>For more information about this release, see * <a href="/about/versions/nougat/android-7.1">Android 7.1 for * Developers</a>. */ @@ -930,6 +968,7 @@ public class Build { /** * O. * + * <p>Released publicly as Android 8.0 in August 2017. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see * the <a href="/about/versions/oreo/">Android Oreo overview</a>.</p> @@ -1020,6 +1059,7 @@ public class Build { /** * O MR1. * + * <p>Released publicly as Android 8.1 in December 2017. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see * <a href="/about/versions/oreo/android-8.1">Android 8.1 features and @@ -1037,6 +1077,7 @@ public class Build { /** * P. * + * <p>Released publicly as Android 9 in August 2018. * <p>Applications targeting this or a later release will get these * new changes in behavior. For more information about this release, see the * <a href="/about/versions/pie/">Android 9 Pie overview</a>.</p> @@ -1054,6 +1095,7 @@ public class Build { /** * Q. * + * <p>Released publicly as Android 10 in September 2019. * <p>Applications targeting this or a later release will get these new changes in behavior. * For more information about this release, see the * <a href="/about/versions/10">Android 10 overview</a>.</p> @@ -1069,6 +1111,7 @@ public class Build { /** * R. * + * <p>Released publicly as Android 11 in September 2020. * <p>Applications targeting this or a later release will get these new changes in behavior. * For more information about this release, see the * <a href="/about/versions/11">Android 11 overview</a>.</p> diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index ff692818863a..ee8353a9f203 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -1969,7 +1969,17 @@ public class ZenModeConfig implements Parcelable { } public boolean isAutomaticActive() { - return enabled && !snoozing && pkg != null && isTrueOrUnknown(); + return enabled && !snoozing && getPkg() != null && isTrueOrUnknown(); + } + + public String getPkg() { + return !TextUtils.isEmpty(pkg) + ? pkg + : (component != null) + ? component.getPackageName() + : (configurationActivity != null) + ? configurationActivity.getPackageName() + : null; } public boolean isTrueOrUnknown() { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 280685065aaf..3550a31f9038 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1955,22 +1955,23 @@ public final class ViewRootImpl implements ViewParent, return mBoundsLayer; } - Surface getOrCreateBLASTSurface(int width, int height, - @Nullable WindowManager.LayoutParams params) { + Surface getOrCreateBLASTSurface() { if (!mSurfaceControl.isValid()) { return null; } - int format = params == null ? PixelFormat.TRANSLUCENT : params.format; Surface ret = null; if (mBlastBufferQueue == null) { - mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, width, height, - format); + mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, + mSurfaceSize.x, mSurfaceSize.y, + mWindowAttributes.format); // We only return the Surface the first time, as otherwise // it hasn't changed and there is no need to update. ret = mBlastBufferQueue.createSurface(); } else { - mBlastBufferQueue.update(mSurfaceControl, width, height, format); + mBlastBufferQueue.update(mSurfaceControl, + mSurfaceSize.x, mSurfaceSize.y, + mWindowAttributes.format); } return ret; @@ -7784,8 +7785,7 @@ public final class ViewRootImpl implements ViewParent, if (!useBLAST()) { mSurface.copyFrom(mSurfaceControl); } else { - final Surface blastSurface = getOrCreateBLASTSurface(mSurfaceSize.x, mSurfaceSize.y, - params); + final Surface blastSurface = getOrCreateBLASTSurface(); // If blastSurface == null that means it hasn't changed since the last time we // called. In this situation, avoid calling transferFrom as we would then // inc the generation ID and cause EGL resources to be recreated. diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java index 472e3e72ab2f..c110ab956030 100644 --- a/core/java/android/widget/EdgeEffect.java +++ b/core/java/android/widget/EdgeEffect.java @@ -365,6 +365,10 @@ public class EdgeEffect { mDuration = PULL_TIME; mPullDistance += deltaDistance; + if (edgeEffectBehavior == TYPE_STRETCH) { + // Don't allow stretch beyond 1 + mPullDistance = Math.min(1f, mPullDistance); + } mDistance = Math.max(0f, mPullDistance); mVelocity = 0; @@ -783,6 +787,10 @@ public class EdgeEffect { + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT)); mDistance = (float) distance / mHeight; mVelocity = (float) velocity; + if (mDistance > 1f) { + mDistance = 1f; + mVelocity = 0f; + } if (isAtEquilibrium()) { mDistance = 0; mVelocity = 0; diff --git a/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java new file mode 100644 index 000000000000..481183e700a2 --- /dev/null +++ b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.widget; + +import android.annotation.Nullable; +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.RemoteViews; + +import java.util.LinkedList; +import java.util.List; + +/** + * This is a subclass of LinearLayout meant to be used in the Conversation header, to fix a bug + * when multiple user-provided strings are shown in the same conversation header. b/189723284 + * + * This works around a deficiency in LinearLayout when shrinking views that it can't fully reduce + * all contents if any of the oversized views reaches zero. + */ +@RemoteViews.RemoteView +public class ConversationHeaderLinearLayout extends LinearLayout { + + public ConversationHeaderLinearLayout(Context context) { + super(context); + } + + public ConversationHeaderLinearLayout(Context context, + @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public ConversationHeaderLinearLayout(Context context, @Nullable AttributeSet attrs, + int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + private int calculateTotalChildLength() { + final int count = getChildCount(); + int totalLength = 0; + + for (int i = 0; i < count; ++i) { + final View child = getChildAt(i); + if (child == null || child.getVisibility() == GONE) { + continue; + } + final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) + child.getLayoutParams(); + totalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; + } + return totalLength + getPaddingLeft() + getPaddingRight(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final int containerWidth = getMeasuredWidth(); + final int contentsWidth = calculateTotalChildLength(); + + int excessContents = contentsWidth - containerWidth; + if (excessContents <= 0) { + return; + } + final int count = getChildCount(); + + float remainingWeight = 0; + List<ViewInfo> visibleChildrenToShorten = null; + + // Find children which need to be shortened in order to ensure the contents fit. + for (int i = 0; i < count; ++i) { + final View child = getChildAt(i); + if (child == null || child.getVisibility() == View.GONE) { + continue; + } + final float weight = ((LayoutParams) child.getLayoutParams()).weight; + if (weight == 0) { + continue; + } + if (child.getMeasuredWidth() == 0) { + continue; + } + if (visibleChildrenToShorten == null) { + visibleChildrenToShorten = new LinkedList<>(); + } + visibleChildrenToShorten.add(new ViewInfo(child)); + remainingWeight += Math.max(0, weight); + } + if (visibleChildrenToShorten == null || visibleChildrenToShorten.isEmpty()) { + return; + } + balanceViewWidths(visibleChildrenToShorten, remainingWeight, excessContents); + remeasureChangedChildren(visibleChildrenToShorten); + } + + /** + * Measure any child with a width that has changed. + */ + private void remeasureChangedChildren(List<ViewInfo> childrenInfo) { + for (ViewInfo info : childrenInfo) { + if (info.mWidth != info.mStartWidth) { + final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( + Math.max(0, info.mWidth), MeasureSpec.EXACTLY); + final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( + info.mView.getMeasuredHeight(), MeasureSpec.EXACTLY); + info.mView.measure(childWidthMeasureSpec, childHeightMeasureSpec); + } + } + } + + /** + * Given a list of view, use the weights to remove width from each view proportionally to the + * weight (and ignoring the view's actual width), but do this iteratively whenever a view is + * reduced to zero width, because in that case other views need reduction. + */ + void balanceViewWidths(List<ViewInfo> viewInfos, float weightSum, int excessContents) { + boolean performAnotherPass = true; + // Loops only when all of the following are true: + // * `performAnotherPass` -- a view clamped to 0 width (or the first iteration) + // * `excessContents > 0` -- there is still horizontal space to allocate + // * `weightSum > 0` -- at least 1 view with nonzero width AND nonzero weight left + while (performAnotherPass && excessContents > 0 && weightSum > 0) { + int excessRemovedDuringThisPass = 0; + float weightSumForNextPass = 0; + performAnotherPass = false; + for (ViewInfo info : viewInfos) { + if (info.mWeight <= 0) { + continue; + } + if (info.mWidth <= 0) { + continue; + } + int newWidth = (int) (info.mWidth - (excessContents * (info.mWeight / weightSum))); + if (newWidth < 0) { + newWidth = 0; + performAnotherPass = true; + } + excessRemovedDuringThisPass += info.mWidth - newWidth; + info.mWidth = newWidth; + if (info.mWidth > 0) { + weightSumForNextPass += info.mWeight; + } + } + excessContents -= excessRemovedDuringThisPass; + weightSum = weightSumForNextPass; + } + } + + /** + * A helper class for measuring children. + */ + static class ViewInfo { + final View mView; + final float mWeight; + final int mStartWidth; + int mWidth; + + ViewInfo(View view) { + this.mView = view; + this.mWeight = ((LayoutParams) view.getLayoutParams()).weight; + this.mStartWidth = this.mWidth = view.getMeasuredWidth(); + } + } +} diff --git a/core/res/res/layout/notification_template_conversation_header.xml b/core/res/res/layout/notification_template_conversation_header.xml index 389637eb2517..2faff412565e 100644 --- a/core/res/res/layout/notification_template_conversation_header.xml +++ b/core/res/res/layout/notification_template_conversation_header.xml @@ -14,7 +14,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<LinearLayout +<com.android.internal.widget.ConversationHeaderLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/conversation_header" android:layout_width="wrap_content" @@ -119,6 +119,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="@dimen/notification_conversation_header_separating_margin" + android:layout_weight="100" android:showRelative="true" android:singleLine="true" android:visibility="gone" @@ -171,4 +172,4 @@ android:src="@drawable/ic_notifications_alerted" android:visibility="gone" /> -</LinearLayout> +</com.android.internal.widget.ConversationHeaderLinearLayout> diff --git a/packages/Shell/res/values-ta/strings.xml b/packages/Shell/res/values-ta/strings.xml index a906abede3fd..30d087368d40 100644 --- a/packages/Shell/res/values-ta/strings.xml +++ b/packages/Shell/res/values-ta/strings.xml @@ -32,7 +32,7 @@ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"மீண்டும் காட்டாதே"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"பிழை அறிக்கைகள்"</string> <string name="bugreport_unreadable_text" msgid="586517851044535486">"பிழை அறிக்கையைப் படிக்க முடியவில்லை"</string> - <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"பிழை அறிக்கை விவரங்களை ஜிப் கோப்பில் சேர்க்க முடியவில்லை"</string> + <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"பிழை அறிக்கை விவரங்களை ஜிப் ஃபைலில் சேர்க்க முடியவில்லை"</string> <string name="bugreport_unnamed" msgid="2800582406842092709">"பெயரிடப்படாதது"</string> <string name="bugreport_info_action" msgid="2158204228510576227">"விவரங்கள்"</string> <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ஸ்கிரீன்ஷாட்"</string> diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java index 95c2d2efcd89..6d1408d5d212 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/DetailAdapter.java @@ -72,7 +72,8 @@ public interface DetailAdapter { } /** - * @return if detail panel should animate when shown or closed + * Indicates whether the detail view wants to animate when shown. This has no affect over the + * closing animation. Detail panels will always animate when closed. */ default boolean shouldAnimate() { return true; diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml index 99e8116cb681..3c9e44e2dba9 100644 --- a/packages/SystemUI/res/layout/auth_biometric_contents.xml +++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml @@ -52,6 +52,7 @@ android:layout_width="@dimen/biometric_dialog_biometric_icon_size" android:layout_height="@dimen/biometric_dialog_biometric_icon_size" android:layout_gravity="center" + android:contentDescription="@null" android:scaleType="fitXY" /> </FrameLayout> diff --git a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml index 892f64b3123b..404365629aba 100644 --- a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml +++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml @@ -131,6 +131,7 @@ <TextView android:id="@+id/messages_count" android:gravity="end" + android:layout_marginStart="-32dp" android:paddingStart="8dp" android:paddingEnd="8dp" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" @@ -147,6 +148,7 @@ android:id="@+id/predefined_icon" android:tint="?android:attr/textColorSecondary" android:gravity="end|center_vertical" + android:layout_marginStart="-24dp" android:layout_width="@dimen/regular_predefined_icon" android:layout_height="@dimen/regular_predefined_icon" /> </LinearLayout> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index bfcfd9bd41d5..6195e5fdb062 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -1173,8 +1173,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"تم إرسال رسالة من <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"تم إرسال صورة من <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="new_status_content_description" msgid="6046637888641308327">"تم تعديل حالة <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"متاح"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 316c87b18df0..bc5a91a6b859 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -427,7 +427,7 @@ <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"আৰম্ভ কৰক"</string> <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"বন্ধ কৰক"</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> + <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইচৰ কেমেৰা অৱৰোধৰ পৰা আঁতৰাবনে?"</string> <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইচৰ কেমেৰা আৰু মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"এইটোৱে আপোনাৰ মাইক্ৰ\'ফ\'ন ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়া আটাইবোৰ এপ্ আৰু সেৱাৰ বাবে এক্সেছ অৱৰোধৰ পৰা আঁতৰায়।"</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"এইটোৱে আপোনাৰ কেমেৰা ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়া আটাইবোৰ এপ্ আৰু সেৱাৰ বাবে এক্সেছ অৱৰোধৰ পৰা আঁতৰায়।"</string> @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>এ এটা বাৰ্তা পঠিয়াইছে: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>এ এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>ৰ এটা স্থিতিৰ আপডে’ট আছে: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"উপলব্ধ"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"আপোনাৰ বেটাৰী মিটাৰ পঢ়োঁতে সমস্যা হৈছে"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনো এলাৰ্ম ছেট কৰা হোৱা নাই"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 452164f2e42a..54790897af76 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mesaj göndərdi: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> şəkil göndərdi"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> status güncəlləməsi edib: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Əlçatan"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya ölçüsünü oxuyarkən problem yarandı"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Siqnal ayarlanmayıb"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 8cbc8bd31e41..491cdcd6917d 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -1161,8 +1161,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> прыслаў паведамленне: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> адправіў відарыс"</string> <string name="new_status_content_description" msgid="6046637888641308327">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> абнавіў стан: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Даступна"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Праблема з чытаннем індыкатара зараду акумулятара"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма будзільнікаў"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 540be62d0f78..a431258e742d 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -431,7 +431,7 @@ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Quieres desbloquear la cámara y el micrófono del dispositivo?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar el micrófono."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar la cámara."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Esta acción desbloquea el acceso para todos los servicios y las apps que tengan permitido usar la cámara o el micrófono."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Esta acción permite que todas las aplicaciones y servicios que tengan permiso puedan usar la cámara o el micrófono."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositivo"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Desliza el dedo hacia arriba para cambiar de app"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra a la derecha para cambiar aplicaciones rápidamente"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 4a5941e38828..e9638538170c 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -431,7 +431,7 @@ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää mikrofoniasi."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää kameraasi."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tämä kumoaa kaikkien sellaisten sovellusten ja palveluiden eston, joilla on lupa käyttää kameraasi tai mikrofoniasi."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Tämä kumoaa eston kaikkien sellaisten sovellusten ja palveluiden osalta, joilla on lupa käyttää kameraasi tai mikrofoniasi."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Laite"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Vaihda sovellusta pyyhkäisemällä ylös"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Vaihda sovellusta nopeasti vetämällä oikealle"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 6e032efb2083..a1c50d8c85a2 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -431,7 +431,7 @@ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre micro."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre appareil photo."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès à tous les services et applis autorisés à utiliser votre appareil photo ou votre micro."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour tous les services et applis autorisés à utiliser votre appareil photo ou votre micro."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Appareil"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Balayer l\'écran vers le haut pour changer d\'application"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Déplacer vers la droite pour changer rapidement d\'application"</string> @@ -1139,7 +1139,7 @@ <string name="audio_status" msgid="4237055636967709208">"Écoute du contenu"</string> <string name="game_status" msgid="1340694320630973259">"Joue"</string> <string name="empty_user_name" msgid="3389155775773578300">"Amis"</string> - <string name="empty_status" msgid="5938893404951307749">"Chattez ce soir !"</string> + <string name="empty_status" msgid="5938893404951307749">"Bavardons ce soir !"</string> <string name="status_before_loading" msgid="1500477307859631381">"Le contenu s\'affichera bientôt"</string> <string name="missed_call" msgid="4228016077700161689">"Appel manqué"</string> <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 9ae4721d8aa0..abbb46a5e451 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -428,10 +428,10 @@ <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"रोकें"</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> - <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"क्या आप डिवाइस के कैमरे और माइक्रोफ़ोन को अनब्लॉक करना चाहते हैं?"</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"क्या आप डिवाइस का कैमरा और माइक्रोफ़ोन अनब्लॉक करना चाहते हैं?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ऐसा करने से, माइक्रोफ़ोन का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें माइक्रोफ़ोन का इस्तेमाल करने की अनुमति दी गई है."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ऐसा करने से, कैमरे का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें कैमरे का इस्तेमाल करने की अनुमति दी गई है."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ऐसा करने से, कैमरे या माइक्रोफ़ोन का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें कैमरे या माइक्रोफ़ोन का इस्तेमाल करने की अनुमति दी गई है."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ऐसा करने से, कैमरा या माइक्रोफ़ोन का ऐक्सेस उन सभी ऐप्लिकेशन और सेवाओं के लिए अनब्लॉक हो जाएगा जिन्हें ये इस्तेमाल करने की अनुमति है."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"डिवाइस"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ऐप्लिकेशन बदलने के लिए ऊपर स्वाइप करें"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ऐप्लिकेशन को झटपट स्विच करने के लिए उसे दाईं ओर खींचें और छोड़ें"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 227bf4d22d3e..ef20347a2576 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -431,7 +431,7 @@ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Berhenti memblokir kamera dan mikrofon perangkat?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan mikrofon."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera atau mikrofon."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Langkah ini akan berhenti memblokir akses untuk semua aplikasi dan layanan yang diizinkan menggunakan kamera atau mikrofon."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Perangkat"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Geser ke atas untuk beralih aplikasi"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tarik ke kanan untuk beralih aplikasi dengan cepat"</string> @@ -1127,7 +1127,7 @@ <string name="over_two_weeks_timestamp" msgid="6300507859007874050">"Lebih dari 2 minggu lalu"</string> <string name="birthday_status" msgid="2596961629465396761">"Ulang Tahun"</string> <string name="birthday_status_content_description" msgid="682836371128282925">"Hari ini ulang tahun <xliff:g id="NAME">%1$s</xliff:g>"</string> - <string name="upcoming_birthday_status" msgid="2005452239256870351">"Ulang tahun segera"</string> + <string name="upcoming_birthday_status" msgid="2005452239256870351">"Segera ulang tahun"</string> <string name="upcoming_birthday_status_content_description" msgid="2165036816803797148">"Ulang tahun <xliff:g id="NAME">%1$s</xliff:g> sebentar lagi"</string> <string name="anniversary_status" msgid="1790034157507590838">"Hari Peringatan"</string> <string name="anniversary_status_content_description" msgid="8212171790843327442">"Hari ini hari jadi <xliff:g id="NAME">%1$s</xliff:g>"</string> @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> mengirim pesan: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> mengirim gambar"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> memposting pembaruan status: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Online"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Terjadi masalah saat membaca indikator baterai"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm tidak disetel"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 65c23d47e043..731d36ca36c1 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -1161,8 +1161,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"התקבלה הודעה מ<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> שלח/ה תמונה"</string> <string name="new_status_content_description" msgid="6046637888641308327">"הסטטוס של <xliff:g id="NAME">%1$s</xliff:g> עודכן: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"אונליין"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה התראה"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 5ce3fe571bdd..aff2521a7bad 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g>-მა გაგზავნა შეტყობინება: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>-მ(ა) სურათი გამოგზავნა"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g>-მა განაახლა სტატუსი: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"ხელმისაწვდომია"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"თქვენი ბატარეის მზომის წაკითხვასთან დაკავშირებით პრობლემა დაფიქსირდა"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"მაღვიძარა არ არის"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index cba176d5953b..674f6a04393c 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> хабар жіберді: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сурет жіберді."</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ағымдағы күйін жаңартты: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Желіде"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батарея зарядының дерегі алынбай жатыр"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Оятқыш орнатылмаған."</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 94df302a007b..264f24834b04 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -428,7 +428,7 @@ <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ನಿಲ್ಲಿಸಿ"</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> - <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ಸಾಧನದ ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೋಫೋನ್ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ಸಾಧನದ ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಅನ್ಬ್ಲಾಕ್ ಮಾಡಬೇಕೇ?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ಇದು ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳಿಗೆ ಹಾಗೂ ಸೇವೆಗಳಿಗೆ ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಬಳಸುವುದಕ್ಕಾಗಿ ಇರುವ ಪ್ರವೇಶದ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ಇದು ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳಿಗೆ ಹಾಗೂ ಸೇವೆಗಳಿಗೆ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸುವುದಕ್ಕಾಗಿ ಇರುವ ಪ್ರವೇಶದ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ."</string> <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ಇದು ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳಿಗೆ ಹಾಗೂ ಸೇವೆಗಳಿಗೆ ನಿಮ್ಮ ಕ್ಯಾಮರಾ ಅಥವಾ ಮೈಕ್ರೋಫೋನ್ ಬಳಸುವುದಕ್ಕಾಗಿ ಇರುವ ಪ್ರವೇಶದ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ."</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 34d799c2a25b..42d684ea34f0 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -426,8 +426,8 @@ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Экрандан видео жаздырып алуу"</string> <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Баштадык"</string> <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Токтотуу"</string> - <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Түзмөктүн микрофонунун кулпусун ачасызбы?"</string> - <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Түзмөктүн камерасынын кулпусун ачасызбы?"</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> <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Түзмөктүн камерасы менен микрофону бөгөттөн чыгарылсынбы?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Микрофонуңузду колдонууга уруксат алган бардык колдонмолор менен кызматтар бөгөттөн чыгат."</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Камераны колдонууга уруксат алган бардык колдонмолор менен кызматтар бөгөттөн чыгат."</string> @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> билдирүү жөнөттү: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сүрөт жөнөттү"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> жаңы абалы тууралуу жарыялады: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Онлайн"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батареяңыздын кубаты аныкталбай жатат"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ойготкуч коюлган жок"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 11d363ed59ef..19e8fbfd623c 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -1161,8 +1161,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė pranešimą: „<xliff:g id="NOTIFICATION">%2$s</xliff:g>“"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė vaizdą"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> atnaujino būseną: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Pasiekiama"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nuskaitant akumuliatoriaus skaitiklį iškilo problema"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenustatyta signalų"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 6b68297dea71..f0d26c837c48 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -432,8 +432,8 @@ <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string> <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vai atbloķēt ierīces kameru un mikrofonu?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot mikrofonu, varēs tam piekļūt."</string> - <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot kameru, varēs tai piekļūt."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Visas lietotnes un pakalpojumi, kurām ir atļauts izmantot kameru vai mikrofonu, varēs tiem piekļūt."</string> + <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Visas lietotnes un pakalpojumi, kuriem ir atļauts izmantot kameru, varēs tai piekļūt."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Visas lietotnes un pakalpojumi, kuriem ir atļauts izmantot kameru vai mikrofonu, varēs tiem piekļūt."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Ierīce"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Velciet augšup, lai pārslēgtu lietotnes"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Lai ātri pārslēgtu lietotnes, velciet pa labi"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 5392d52526f3..719f519f3405 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> испрати порака: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> испрати слика"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> има ажурирање на статусот: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Достапен"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем при читањето на мерачот на батеријата"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Не е поставен аларм"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index bf27df9c63f9..2e6f01b515e3 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> यांनी मेसेज पाठवला: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> यांनी इमेज पाठवली"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> यांनी स्टेटस अपडेट केले: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"उपलब्ध आहे"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"तुमचे बॅटरी मीटर वाचताना समस्या आली"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म सेट केला नाही"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 1d16edcdc49c..684d71850351 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> menghantar mesej: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> menghantar imej"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> mempunyai kemaskinian status: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Tersedia"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Masalah membaca meter bateri anda"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Tiada penggera"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index c92a45e8dbcc..d588d271fb6f 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -376,7 +376,7 @@ <string name="quick_settings_cast_title" msgid="2279220930629235211">"မျက်နှာပြင် ကာ့စ်လုပ်ခြင်း"</string> <string name="quick_settings_casting" msgid="1435880708719268055">"ကာစ်တင်"</string> <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"အမည်မတပ် ကိရိယာ"</string> - <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"ကာစ်တ် လုပ်ရန် အသင့် ရှိနေပြီ"</string> + <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"ကာစ် လုပ်ရန် အသင့် ရှိနေပြီ"</string> <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"ကိရိယာများ မရှိ"</string> <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi ချိတ်ဆက်ထားခြင်းမရှိပါ"</string> <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"အလင်းတောက်ပမှု"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 2ad54f7fd75a..b8a104fc5a04 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ମେସେଜ୍ ପଠାଇଛନ୍ତି: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ଛବି ପଠାଇଛନ୍ତି"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ସ୍ଥିତି ଅପଡେଟ୍ କରିଛନ୍ତି: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"ଉପଲବ୍ଧ"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ମିଟର୍ ପଢ଼ିବାରେ ସମସ୍ୟା ହେଉଛି"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ଆଲାରାମ ସେଟ୍ ହୋଇନାହିଁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 3f2e4810dbd2..708462f94553 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -431,7 +431,7 @@ <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string> <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਗਈ ਹੈ।"</string> <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਕੈਮਰਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਗਈ ਹੈ।"</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਕੈਮਰਾ ਜਾਂ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਗਈ ਹੈ।"</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"ਇਹ ਉਹਨਾਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਪਹੁੰਚ ਨੂੰ ਅਣਬਲਾਕ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਹਾਡਾ ਕੈਮਰਾ ਜਾਂ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਗਈ ਹੈ।"</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"ਡੀਵਾਈਸ"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ਐਪਾਂ ਵਿਚਾਲੇ ਤੇਜ਼ੀ ਨਾਲ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਘਸੀਟੋ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 990b461fe0f9..b8da6bbedc53 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -748,10 +748,10 @@ <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"<b>Stan:</b> zmieniono na Ciche"</string> <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"<b>Stan:</b> podniesiono ważność"</string> <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"<b>Stan:</b> obniżono ważność"</string> - <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady"</string> - <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady, jako dymek"</string> - <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady, przerywa działanie trybu Nie przeszkadzać"</string> - <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekran blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string> + <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady"</string> + <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek"</string> + <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, przerywa działanie trybu Nie przeszkadzać"</string> + <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Ustawienia"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Priorytetowe"</string> <string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 346323685e83..cf957a45dbdd 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -1155,8 +1155,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a trimis un mesaj: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a trimis o imagine"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> are o nouă stare: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Disponibil"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problemă la citirea măsurării bateriei"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atingeți pentru mai multe informații"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nicio alarmă setată"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 53500b5d8b1e..9fd91f191837 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -1161,8 +1161,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил сообщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил изображение"</string> <string name="new_status_content_description" msgid="6046637888641308327">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> обновил статус: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Онлайн"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удалось узнать уровень заряда батареи"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Будильников нет"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 4967718196ef..14aa0a7bc303 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -1161,8 +1161,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) správu: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) obrázok"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> má aktualizáciu statusu: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"K dispozícii"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pri čítaní meradla batérie sa vyskytol problém"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Žiadny budík"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index ad8e2659b612..5ce3cd43eef9 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një mesazh: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një imazh"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> ka një përditësim të statusit: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"I disponueshëm"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem me leximin e matësit të baterisë"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nuk është caktuar asnjë alarm"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 6e0662693d4a..69b499985632 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> ส่งข้อความ: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ส่งรูปภาพ"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> มีการอัปเดตสถานะ: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"มี"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"พบปัญหาในการอ่านเครื่องวัดแบตเตอรี่"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ไม่มีการตั้งปลุก"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 9a83c227bf32..d65f16dba762 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng mensahe: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng larawan"</string> <string name="new_status_content_description" msgid="6046637888641308327">"May update sa status si <xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"Available"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nagkaproblema sa pagbabasa ng iyong battery meter"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"I-tap para sa higit pang impormasyon"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Walang alarm"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 2d1500965136..d4d18162e07f 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -433,9 +433,9 @@ <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string> <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Надати доступ до камери пристрою?"</string> <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Надати доступ до камери й мікрофона?"</string> - <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Усі додатки та сервіси, які можуть користуватися вашим мікрофоном, отримають доступ."</string> - <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Усі додатки та сервіси, які можуть користуватися вашою камерою, отримають доступ."</string> - <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Усі додатки та сервіси, які можуть користуватися вашою камерою чи мікрофоном, отримають доступ."</string> + <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Усі додатки та сервіси, яким дозволено користуватися вашим мікрофоном, отримають доступ."</string> + <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Усі додатки та сервіси, яким дозволено користуватися вашою камерою, отримають доступ."</string> + <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Усі додатки та сервіси, яким дозволено користуватися вашою камерою чи мікрофоном, отримають доступ."</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Пристрій"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Проводьте пальцем угору, щоб переходити між додатками"</string> <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Перетягуйте праворуч, щоб швидко переходити між додатками"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index ffcd9a750abf..e8cb65725514 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -1149,8 +1149,7 @@ <string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک پیغام بھیجا: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک تصویر بھیجی"</string> <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> نے اسٹیٹس کو اپ ڈیٹ کر دیا ہے: <xliff:g id="STATUS">%2$s</xliff:g>"</string> - <!-- no translation found for person_available (2318599327472755472) --> - <skip /> + <string name="person_available" msgid="2318599327472755472">"دستیاب ہے"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index ea79e3c94840..e432c620c3ab 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -211,8 +211,8 @@ <string name="accessibility_two_bars" msgid="1335676987274417121">"信号强度为两格。"</string> <string name="accessibility_three_bars" msgid="819417766606501295">"信号强度为三格。"</string> <string name="accessibility_signal_full" msgid="5920148525598637311">"信号满格。"</string> - <string name="accessibility_desc_on" msgid="2899626845061427845">"开启。"</string> - <string name="accessibility_desc_off" msgid="8055389500285421408">"关闭。"</string> + <string name="accessibility_desc_on" msgid="2899626845061427845">"已开启。"</string> + <string name="accessibility_desc_off" msgid="8055389500285421408">"已关闭。"</string> <string name="accessibility_desc_connected" msgid="3082590384032624233">"已连接。"</string> <string name="accessibility_desc_connecting" msgid="8011433412112903614">"正在连接。"</string> <string name="data_connection_hspa" msgid="6096234094857660873">"HSPA"</string> @@ -221,7 +221,7 @@ <string name="accessibility_no_sim" msgid="1140839832913084973">"无 SIM 卡。"</string> <string name="accessibility_cell_data" msgid="172950885786007392">"移动数据"</string> <string name="accessibility_cell_data_on" msgid="691666434519443162">"移动数据已开启"</string> - <string name="cell_data_off" msgid="4886198950247099526">"关闭"</string> + <string name="cell_data_off" msgid="4886198950247099526">"已关闭"</string> <string name="accessibility_bluetooth_tether" msgid="6327291292208790599">"蓝牙网络共享。"</string> <string name="accessibility_airplane_mode" msgid="1899529214045998505">"飞行模式。"</string> <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN 已开启。"</string> @@ -706,8 +706,8 @@ <string name="do_not_silence" msgid="4982217934250511227">"不静音"</string> <string name="do_not_silence_block" msgid="4361847809775811849">"不静音也不屏蔽"</string> <string name="tuner_full_importance_settings" msgid="1388025816553459059">"高级通知设置"</string> - <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"开启"</string> - <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"关闭"</string> + <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"已开启"</string> + <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"已关闭"</string> <string name="power_notification_controls_description" msgid="1334963837572708952">"利用高级通知设置,您可以为应用通知设置从 0 级到 5 级的重要程度等级。\n\n"<b>"5 级"</b>" \n- 在通知列表顶部显示 \n- 允许全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"4 级"</b>" \n- 禁止全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"3 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n\n"<b>"2 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n\n"<b>"1 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n- 不在锁定屏幕和状态栏中显示 \n- 在通知列表底部显示 \n\n"<b>"0 级"</b>" \n- 屏蔽应用的所有通知"</string> <string name="notification_header_default_channel" msgid="225454696914642444">"通知"</string> <string name="notification_channel_disabled" msgid="928065923928416337">"您将不会再看到这些通知"</string> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 9bed6001e3de..7485ef858620 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1480,6 +1480,8 @@ <dimen name="content_text_size_for_large">14sp</dimen> <dimen name="below_name_text_padding">16dp</dimen> <dimen name="above_notification_text_padding">22dp</dimen> + <dimen name="before_messages_count_padding">40dp</dimen> + <dimen name="before_predefined_icon_padding">30dp</dimen> <dimen name="regular_predefined_icon">18dp</dimen> <dimen name="larger_predefined_icon">24dp</dimen> <dimen name="largest_predefined_icon">32dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java index 45ee4ad9ae50..ee602bc9cb78 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java @@ -23,6 +23,8 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; +import androidx.annotation.Nullable; + import com.android.systemui.R; public class AuthBiometricFingerprintView extends AuthBiometricView { @@ -94,12 +96,37 @@ public class AuthBiometricFingerprintView extends AuthBiometricView { mIconView.setImageDrawable(icon); + final CharSequence iconContentDescription = getIconContentDescription(newState); + if (iconContentDescription != null) { + mIconView.setContentDescription(iconContentDescription); + } + if (animation != null && shouldAnimateForTransition(lastState, newState)) { animation.forceAnimationOnUI(); animation.start(); } } + @Nullable + private CharSequence getIconContentDescription(int newState) { + switch (newState) { + case STATE_IDLE: + case STATE_AUTHENTICATING_ANIMATING_IN: + case STATE_AUTHENTICATING: + case STATE_PENDING_CONFIRMATION: + case STATE_AUTHENTICATED: + return mContext.getString( + R.string.accessibility_fingerprint_dialog_fingerprint_icon); + + case STATE_ERROR: + case STATE_HELP: + return mContext.getString(R.string.biometric_dialog_try_again); + + default: + return null; + } + } + private boolean shouldAnimateForTransition(int oldState, int newState) { switch (newState) { case STATE_HELP: diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java index bebf813e1833..60b06378a61a 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java @@ -636,7 +636,6 @@ public abstract class AuthBiometricView extends LinearLayout { mIndicatorView.setText(message); mIndicatorView.setTextColor(mTextColorError); mIndicatorView.setVisibility(View.VISIBLE); - mIndicatorView.setSelected(true); mHandler.postDelayed(resetMessageRunnable, mInjector.getDelayAfterError()); Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index e51baed065ef..04dd990929fa 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -698,7 +698,8 @@ public class UdfpsController implements DozeReceiver { // This view overlaps the sensor area, so prevent it from being selectable // during a11y. if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR - || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) { + || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING + || reason == IUdfpsOverlayController.REASON_AUTH_BP) { mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index c33f4fa8dee4..c7c25903923a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2311,7 +2311,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, // only play "unlock" noises if not on a call (since the incall UI // disables the keyguard) if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { - Log.i("TEST", "playSounds: false"); playSounds(false); } diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java index 35115144cc05..a16b92f494a4 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java @@ -181,6 +181,7 @@ public class PeopleTileViewHelper { private int mWidth; private int mHeight; private int mLayoutSize; + private boolean mIsLeftToRight; private Locale mLocale; private NumberFormat mIntegerFormat; @@ -195,6 +196,8 @@ public class PeopleTileViewHelper { mWidth = width; mHeight = height; mLayoutSize = getLayoutSize(); + mIsLeftToRight = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) + == View.LAYOUT_DIRECTION_LTR; } /** @@ -659,7 +662,7 @@ public class PeopleTileViewHelper { private RemoteViews createMissedCallRemoteViews() { RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(), getLayoutForContent())); - views.setViewVisibility(R.id.predefined_icon, View.VISIBLE); + setPredefinedIconVisible(views); views.setViewVisibility(R.id.text_content, View.VISIBLE); views.setViewVisibility(R.id.messages_count, View.GONE); setMaxLines(views, false); @@ -678,6 +681,17 @@ public class PeopleTileViewHelper { return views; } + private void setPredefinedIconVisible(RemoteViews views) { + views.setViewVisibility(R.id.predefined_icon, View.VISIBLE); + if (mLayoutSize == LAYOUT_MEDIUM) { + int endPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.before_predefined_icon_padding); + views.setViewPadding(R.id.name, mIsLeftToRight ? 0 : endPadding, 0, + mIsLeftToRight ? endPadding : 0, + 0); + } + } + private RemoteViews createNotificationRemoteViews() { RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(), getLayoutForNotificationContent())); @@ -717,6 +731,13 @@ public class PeopleTileViewHelper { views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message); } if (mTile.getMessagesCount() > 1) { + if (mLayoutSize == LAYOUT_MEDIUM) { + int endPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.before_messages_count_padding); + views.setViewPadding(R.id.name, mIsLeftToRight ? 0 : endPadding, 0, + mIsLeftToRight ? endPadding : 0, + 0); + } views.setViewVisibility(R.id.messages_count, View.VISIBLE); views.setTextViewText(R.id.messages_count, getMessagesCountText(mTile.getMessagesCount())); @@ -803,7 +824,7 @@ public class PeopleTileViewHelper { if (TextUtils.isEmpty(statusText)) { statusText = getStatusTextByType(status.getActivity()); } - views.setViewVisibility(R.id.predefined_icon, View.VISIBLE); + setPredefinedIconVisible(views); views.setTextViewText(R.id.text_content, statusText); if (status.getActivity() == ACTIVITY_BIRTHDAY @@ -913,13 +934,11 @@ public class PeopleTileViewHelper { * on the status layouts compared to all other layouts. */ private void setAvailabilityDotPadding(RemoteViews views, int resId) { - boolean isLeftToRight = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) - == View.LAYOUT_DIRECTION_LTR; int startPadding = mContext.getResources().getDimensionPixelSize(resId); int bottomPadding = mContext.getResources().getDimensionPixelSize( R.dimen.medium_content_padding_above_name); views.setViewPadding(R.id.medium_content, - isLeftToRight ? startPadding : 0, 0, isLeftToRight ? 0 : startPadding, + mIsLeftToRight ? startPadding : 0, 0, mIsLeftToRight ? 0 : startPadding, bottomPadding); } @@ -1117,6 +1136,7 @@ public class PeopleTileViewHelper { views.setViewPadding(R.id.content, horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); + views.setViewPadding(R.id.name, 0, 0, 0, 0); // Expand the name font on medium if there's space. int heightRequiredForMaxContentText = (int) (mContext.getResources().getDimension( R.dimen.medium_height_for_max_name_text_size) / mDensity); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java index 1d6c7c94dcc3..929927e5d4e4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java @@ -212,6 +212,11 @@ public class QSDetail extends LinearLayout { Dependency.get(CommandQueue.class).animateCollapsePanels(); mTriggeredExpand = false; } + // Always animate on close, even if the last opened detail adapter had shouldAnimate() + // return false. This is necessary to avoid a race condition which could leave the + // keyguard in a bad state where QS remains visible underneath the notifications, clock, + // and status area. + mShouldAnimate = true; } boolean visibleDiff = wasShowingDetail != showingDetail; @@ -245,10 +250,15 @@ public class QSDetail extends LinearLayout { mClosingDetail = true; mDetailAdapter = null; listener = mTeardownDetailWhenDone; - mHeader.setVisibility(View.VISIBLE); - mFooter.setVisibility(View.VISIBLE); - mQsPanelController.setGridContentVisibility(true); - mQsPanelCallback.onScanStateChanged(false); + // Only update visibility if already expanded. Otherwise, a race condition can cause the + // keyguard to enter a bad state where the QS tiles are displayed underneath the + // notifications, clock, and status area. + if (mQsPanelController.isExpanded()) { + mHeader.setVisibility(View.VISIBLE); + mFooter.setVisibility(View.VISIBLE); + mQsPanelController.setGridContentVisibility(true); + mQsPanelCallback.onScanStateChanged(false); + } } sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); animateDetailVisibleDiff(x, y, visibleDiff, listener); 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 e65038b32bf0..f460a132d65c 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 @@ -148,8 +148,22 @@ public class StackScrollAlgorithm { AmbientState ambientState) { NotificationShelf shelf = ambientState.getShelf(); - if (shelf != null) { - shelf.updateState(algorithmState, ambientState); + if (shelf == null) { + return; + } + + shelf.updateState(algorithmState, ambientState); + + // After the shelf has updated its yTranslation, + // explicitly hide views below the shelf to skip rendering them in the hardware layer. + final float shelfTop = shelf.getViewState().yTranslation; + + for (ExpandableView view : algorithmState.visibleChildren) { + final float viewTop = view.getViewState().yTranslation; + + if (viewTop >= shelfTop) { + view.getViewState().hidden = true; + } } } @@ -411,8 +425,7 @@ public class StackScrollAlgorithm { } else { if (view != ambientState.getTrackedHeadsUpRow()) { if (ambientState.isExpansionChanging()) { - // Show all views. Views below the shelf will later be clipped (essentially - // hidden) in NotificationShelf. + // We later update shelf state, then hide views below the shelf. viewState.hidden = false; viewState.inShelf = algorithmState.firstViewInShelf != null && i >= algorithmState.visibleChildren.indexOf( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 16f8319928bb..91d503bac4fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -74,6 +74,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.settingslib.Utils; import com.android.systemui.ActivityIntentHelper; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -459,6 +460,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL if (tileIcon != null) { mWalletButton.setImageDrawable(tileIcon); } + mWalletButton.getDrawable().setTint( + Utils.getColorAttr( + mContext, + com.android.internal.R.attr.textColorPrimary).getDefaultColor()); mWalletButton.setVisibility(VISIBLE); mWalletButton.setOnClickListener(this::onWalletClick); mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index d6ea4a828395..8c0dfc5f7ab4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -87,7 +87,7 @@ public class KeyguardBouncer { private final Runnable mResetRunnable = ()-> { if (mKeyguardViewController != null) { mKeyguardViewController.resetSecurityContainer(); - for (KeyguardResetCallback callback : mResetCallbacks) { + for (KeyguardResetCallback callback : new ArrayList<>(mResetCallbacks)) { callback.onKeyguardReset(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index f52aad96ce69..3c1892d4b7ea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -113,6 +113,7 @@ import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.qs.QSDetailDisplayer; +import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FeatureFlags; @@ -327,6 +328,7 @@ public class NotificationPanelViewController extends PanelViewController { private final int mMaxKeyguardNotifications; private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; private final TapAgainViewController mTapAgainViewController; + private final RecordingController mRecordingController; private boolean mShouldUseSplitNotificationShade; // Current max allowed keyguard notifications determined by measuring the panel private int mMaxAllowedKeyguardNotifications; @@ -711,6 +713,7 @@ public class NotificationPanelViewController extends PanelViewController { FragmentService fragmentService, ContentResolver contentResolver, QuickAccessWalletController quickAccessWalletController, + RecordingController recordingController, @Main Executor uiExecutor, SecureSettings secureSettings, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, @@ -755,6 +758,7 @@ public class NotificationPanelViewController extends PanelViewController { mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); setPanelAlpha(255, false /* animate */); mCommandQueue = commandQueue; + mRecordingController = recordingController; mDisplayId = displayId; mPulseExpansionHandler = pulseExpansionHandler; mDozeParameters = dozeParameters; @@ -1571,7 +1575,10 @@ public class NotificationPanelViewController extends PanelViewController { public void expandWithQsDetail(DetailAdapter qsDetailAdapter) { traceQsJank(true /* startTracing */, false /* wasCancelled */); flingSettings(0 /* velocity */, FLING_EXPAND); - mQSDetailDisplayer.showDetailAdapter(qsDetailAdapter, 0, 0); + // When expanding with a panel, there's no meaningful touch point to correspond to. Set the + // origin to somewhere above the screen. This is used for animations. + int x = mQsFrame.getWidth() / 2; + mQSDetailDisplayer.showDetailAdapter(qsDetailAdapter, x, -getHeight()); if (mAccessibilityManager.isEnabled()) { mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle()); } @@ -2359,7 +2366,8 @@ public class NotificationPanelViewController extends PanelViewController { // The padding on this area is large enough that we can use a cheaper clipping strategy mKeyguardStatusAreaClipBounds.set(left, top, right, bottom); clipStatusView = qsVisible; - radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius, + float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius; + radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius, Math.min(top / (float) mScrimCornerRadius, 1f)); statusBarClipTop = top - mKeyguardStatusBar.getTop(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java index 022faf78b946..5e105bb64350 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java @@ -55,16 +55,18 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.google.android.collect.Lists; - import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; +import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.inject.Inject; @@ -100,7 +102,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW private ForcePluginOpenListener mForcePluginOpenListener; private Consumer<Integer> mScrimsVisibilityListener; private final ArrayList<WeakReference<StatusBarWindowCallback>> - mCallbacks = Lists.newArrayList(); + mCallbacks = new ArrayList<>(); private final SysuiColorExtractor mColorExtractor; private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; @@ -464,13 +466,15 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW @Override public void notifyStateChangedCallbacks() { - for (int i = 0; i < mCallbacks.size(); i++) { - StatusBarWindowCallback cb = mCallbacks.get(i).get(); - if (cb != null) { - cb.onStateChanged(mCurrentState.mKeyguardShowing, - mCurrentState.mKeyguardOccluded, - mCurrentState.mBouncerShowing); - } + // Copy callbacks to separate ArrayList to avoid concurrent modification + List<StatusBarWindowCallback> activeCallbacks = mCallbacks.stream() + .map(Reference::get) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + for (StatusBarWindowCallback cb : activeCallbacks) { + cb.onStateChanged(mCurrentState.mKeyguardShowing, + mCurrentState.mKeyguardOccluded, + mCurrentState.mBouncerShowing); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index 081fe5a47626..a8097c4d74b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.HashSet; /** @@ -157,7 +158,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { NotificationPeekEvent.NOTIFICATION_PEEK, entry.getSbn().getUid(), entry.getSbn().getPackageName(), entry.getSbn().getInstanceId()); } - for (OnHeadsUpChangedListener listener : mListeners) { + for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) { if (isPinned) { listener.onHeadsUpPinned(entry); } else { @@ -177,7 +178,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { entry.setHeadsUp(true); setEntryPinned((HeadsUpEntry) alertEntry, shouldHeadsUpBecomePinned(entry)); EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 1 /* visible */); - for (OnHeadsUpChangedListener listener : mListeners) { + for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) { listener.onHeadsUpStateChanged(entry, true); } } @@ -188,7 +189,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { entry.setHeadsUp(false); setEntryPinned((HeadsUpEntry) alertEntry, false /* isPinned */); EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 0 /* visible */); - for (OnHeadsUpChangedListener listener : mListeners) { + for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) { listener.onHeadsUpStateChanged(entry, false); } } @@ -206,7 +207,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { if (mHasPinnedNotification) { MetricsLogger.count(mContext, "note_peek", 1); } - for (OnHeadsUpChangedListener listener : mListeners) { + for (OnHeadsUpChangedListener listener : new ArrayList<>(mListeners)) { listener.onHeadsUpPinnedModeChanged(hasPinnedNotification); } } 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 b18dfd2866c4..bbaf65a399a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -807,7 +807,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void onEditTextFocusChanged(RemoteEditText remoteEditText, boolean focused) { - for (View.OnFocusChangeListener listener : mEditTextFocusChangeListeners) { + for (View.OnFocusChangeListener listener : new ArrayList<>(mEditTextFocusChangeListeners)) { listener.onFocusChange(remoteEditText, focused); } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java index 361604c461b4..a40cf4f37cc3 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java @@ -101,7 +101,12 @@ abstract public class SafetyWarningDialog extends SystemUIDialog @Override public void onDismiss(DialogInterface unused) { - mContext.unregisterReceiver(mReceiver); + try { + mContext.unregisterReceiver(mReceiver); + } catch (IllegalArgumentException e) { + // Don't crash if the receiver has already been unregistered. + e.printStackTrace(); + } cleanUp(); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 5de7846a820e..3320852ca1f4 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -1743,7 +1743,7 @@ public class VolumeDialogImpl implements VolumeDialog, mContext, android.R.attr.colorBackgroundFloating); final ColorStateList inverseTextTint = Utils.getColorAttr( - mContext, com.android.internal.R.attr.textColorPrimaryInverse); + mContext, com.android.internal.R.attr.textColorOnAccent); row.sliderProgressSolid.setTintList(colorTint); if (row.sliderBgIcon != null) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java index c2bd024f0375..84776c7eb18f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java @@ -148,8 +148,10 @@ public class QSDetailTest extends SysuiTestCase { eq(true) /* in */, any()); clearInvocations(mQsDetail.mClipper); + // Detail adapters should always animate on close. shouldAnimate() should only affect the + // open transition mQsDetail.handleShowingDetail(null, 0, 0, false); - verify(mQsDetail.mClipper).updateCircularClip(eq(false) /* animate */, anyInt(), anyInt(), + verify(mQsDetail.mClipper).updateCircularClip(eq(true) /* animate */, anyInt(), anyInt(), eq(false) /* in */, any()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index a6fc02d7dafc..f8fc22495d8d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -94,6 +94,7 @@ import com.android.systemui.media.MediaHierarchyManager; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.qs.QSDetailDisplayer; +import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.KeyguardAffordanceView; @@ -295,6 +296,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { private NotificationRemoteInputManager mNotificationRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; + @Mock + private RecordingController mRecordingController; private SysuiStatusBarStateController mStatusBarStateController; private NotificationPanelViewController mNotificationPanelViewController; @@ -433,6 +436,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mFragmentService, mContentResolver, mQuickAccessWalletController, + mRecordingController, new FakeExecutor(new FakeSystemClock()), mSecureSettings, mUnlockedScreenOffAnimationController, diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index b144ff27c993..16a0b7e39a07 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -372,7 +372,7 @@ public class ZenModeHelper { } } if (rule.enabled != automaticZenRule.isEnabled()) { - dispatchOnAutomaticRuleStatusChanged(mConfig.user, rule.pkg, ruleId, + dispatchOnAutomaticRuleStatusChanged(mConfig.user, rule.getPkg(), ruleId, automaticZenRule.isEnabled() ? AUTOMATIC_RULE_STATUS_ENABLED : AUTOMATIC_RULE_STATUS_DISABLED); } @@ -391,13 +391,14 @@ public class ZenModeHelper { if (ruleToRemove == null) return false; if (canManageAutomaticZenRule(ruleToRemove)) { newConfig.automaticRules.remove(id); - if (ruleToRemove.pkg != null && !"android".equals(ruleToRemove.pkg)) { + if (ruleToRemove.getPkg() != null && !"android".equals(ruleToRemove.getPkg())) { for (ZenRule currRule : newConfig.automaticRules.values()) { - if (currRule.pkg != null && currRule.pkg.equals(ruleToRemove.pkg)) { + if (currRule.getPkg() != null + && currRule.getPkg().equals(ruleToRemove.getPkg())) { break; // no need to remove from cache } } - mRulesUidCache.remove(getPackageUserKey(ruleToRemove.pkg, newConfig.user)); + mRulesUidCache.remove(getPackageUserKey(ruleToRemove.getPkg(), newConfig.user)); } if (DEBUG) Log.d(TAG, "removeZenRule zenRule=" + id + " reason=" + reason); } else { @@ -405,7 +406,7 @@ public class ZenModeHelper { "Cannot delete rules not owned by your condition provider"); } dispatchOnAutomaticRuleStatusChanged( - mConfig.user, ruleToRemove.pkg, id, AUTOMATIC_RULE_STATUS_REMOVED); + mConfig.user, ruleToRemove.getPkg(), id, AUTOMATIC_RULE_STATUS_REMOVED); return setConfigLocked(newConfig, reason, null, true); } } @@ -417,14 +418,7 @@ public class ZenModeHelper { newConfig = mConfig.copy(); for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) { ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i)); - String pkg = rule.pkg != null - ? rule.pkg - : (rule.component != null) - ? rule.component.getPackageName() - : (rule.configurationActivity != null) - ? rule.configurationActivity.getPackageName() - : null; - if (Objects.equals(pkg, packageName) && canManageAutomaticZenRule(rule)) { + if (Objects.equals(rule.getPkg(), packageName) && canManageAutomaticZenRule(rule)) { newConfig.automaticRules.removeAt(i); } } @@ -524,7 +518,7 @@ public class ZenModeHelper { if (packages != null) { final int packageCount = packages.length; for (int i = 0; i < packageCount; i++) { - if (packages[i].equals(rule.pkg)) { + if (packages[i].equals(rule.getPkg())) { return true; } } @@ -834,8 +828,8 @@ public class ZenModeHelper { ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i)); if (RULE_INSTANCE_GRACE_PERIOD < (currentTime - rule.creationTime)) { try { - if (rule.pkg != null) { - mPm.getPackageInfo(rule.pkg, PackageManager.MATCH_ANY_USER); + if (rule.getPkg() != null) { + mPm.getPackageInfo(rule.getPkg(), PackageManager.MATCH_ANY_USER); } } catch (PackageManager.NameNotFoundException e) { newConfig.automaticRules.removeAt(i); @@ -1246,7 +1240,7 @@ public class ZenModeHelper { } // Look for packages and enablers, enablers get priority. - String pkg = rule.pkg == null ? "" : rule.pkg; + String pkg = rule.getPkg() == null ? "" : rule.getPkg(); if (rule.enabler != null) { pkg = rule.enabler; id = ZenModeConfig.MANUAL_RULE_ID; diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java index 9026262db897..ab7135526746 100644 --- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java +++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java @@ -189,12 +189,16 @@ public abstract class SoftRestrictedPermissionPolicy { return false; } - // 3. The app has WRITE_MEDIA_STORAGE, OR - // the app already has legacy external storage or requested it, - // and is < R. - return hasWriteMediaStorageGrantedForUid - || ((hasLegacyExternalStorage || hasRequestedLegacyExternalStorage) - && targetSDK < Build.VERSION_CODES.R); + // 3. The app targetSDK should be less than R + if (targetSDK >= Build.VERSION_CODES.R) { + return false; + } + + // 4. The app has WRITE_MEDIA_STORAGE, + // OR the app already has legacy external storage + // OR the app requested legacy external storage + return hasWriteMediaStorageGrantedForUid || hasLegacyExternalStorage + || hasRequestedLegacyExternalStorage; } @Override public boolean mayDenyExtraAppOpIfGranted() { @@ -216,10 +220,8 @@ public abstract class SoftRestrictedPermissionPolicy { return true; } - // The package doesn't have WRITE_MEDIA_STORAGE, - // AND didn't request legacy storage to be preserved - if (!hasWriteMediaStorageGrantedForUid - && !hasRequestedPreserveLegacyExternalStorage) { + // The package doesn't request legacy storage to be preserved + if (!hasRequestedPreserveLegacyExternalStorage) { return true; } diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java index 03863723a5e9..dd4e260c6d91 100644 --- a/services/core/java/com/android/server/vibrator/VibrationThread.java +++ b/services/core/java/com/android/server/vibrator/VibrationThread.java @@ -1294,21 +1294,32 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient { @Override public boolean shouldPlayWhenVibratorComplete(int vibratorId) { if (controller.getVibratorInfo().getId() == vibratorId) { + mVibratorCallbackReceived = true; mNextOffTime = SystemClock.uptimeMillis(); } - // Timings are tightly controlled here, so never anticipate when vibrator is complete. - return false; + // Timings are tightly controlled here, so only anticipate if the vibrator was supposed + // to be ON but has completed prematurely, to turn it back on as soon as possible. + return mNextOffTime < startTime && controller.getCurrentAmplitude() > 0; } @Override public List<Step> play() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "AmplitudeStep"); try { + long now = SystemClock.uptimeMillis(); + long latency = now - startTime; if (DEBUG) { - long latency = SystemClock.uptimeMillis() - startTime; Slog.d(TAG, "Running amplitude step with " + latency + "ms latency."); } + if (mVibratorCallbackReceived && latency < 0) { + // This step was anticipated because the vibrator turned off prematurely. + // Turn it back on and return this same step to run at the exact right time. + mNextOffTime = turnVibratorBackOn(/* remainingDuration= */ -latency); + return Arrays.asList(new AmplitudeStep(startTime, controller, effect, + segmentIndex, mNextOffTime)); + } + VibrationEffectSegment segment = effect.getSegments().get(segmentIndex); if (!(segment instanceof StepSegment)) { Slog.w(TAG, "Ignoring wrong segment for a AmplitudeStep: " + segment); @@ -1321,17 +1332,16 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient { return skipToNextSteps(/* segmentsSkipped= */ 1); } - long now = SystemClock.uptimeMillis(); float amplitude = stepSegment.getAmplitude(); if (amplitude == 0) { - if (mNextOffTime > now) { + if (vibratorOffTimeout > now) { // Amplitude cannot be set to zero, so stop the vibrator. stopVibrating(); mNextOffTime = now; } } else { if (startTime >= mNextOffTime) { - // Vibrator has stopped. Turn vibrator back on for the duration of another + // Vibrator is OFF. Turn vibrator back on for the duration of another // cycle before setting the amplitude. long onDuration = getVibratorOnDuration(effect, segmentIndex); if (onDuration > 0) { @@ -1350,6 +1360,22 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient { } } + private long turnVibratorBackOn(long remainingDuration) { + long onDuration = getVibratorOnDuration(effect, segmentIndex); + if (onDuration <= 0) { + // Vibrator is supposed to go back off when this step starts, so just leave it off. + return vibratorOffTimeout; + } + onDuration += remainingDuration; + float expectedAmplitude = controller.getCurrentAmplitude(); + mVibratorOnResult = startVibrating(onDuration); + if (mVibratorOnResult > 0) { + // Set the amplitude back to the value it was supposed to be playing at. + changeAmplitude(expectedAmplitude); + } + return SystemClock.uptimeMillis() + onDuration + CALLBACKS_EXTRA_TIMEOUT; + } + private long startVibrating(long duration) { if (DEBUG) { Slog.d(TAG, "Turning on vibrator " + controller.getVibratorInfo().getId() + " for " @@ -1383,7 +1409,10 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient { repeatIndex = -1; } if (i == startIndex) { - return 1000; + // The repeating waveform keeps the vibrator ON all the time. Use a minimum + // of 1s duration to prevent short patterns from turning the vibrator ON too + // frequently. + return Math.max(timing, 1000); } } if (i == segmentCount && effect.getRepeatIndex() < 0) { diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index 583797e69995..a254f68e8bed 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -514,8 +514,16 @@ public class AlarmManagerServiceTest { } private void setAllowWhileIdleAlarm(int type, long triggerTime, PendingIntent pi, - boolean unrestricted) { - final int flags = unrestricted ? FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED : FLAG_ALLOW_WHILE_IDLE; + boolean unrestricted, boolean compat) { + assertFalse("Alarm cannot be compat and unrestricted", unrestricted && compat); + final int flags; + if (unrestricted) { + flags = FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; + } else if (compat) { + flags = FLAG_ALLOW_WHILE_IDLE_COMPAT; + } else { + flags = FLAG_ALLOW_WHILE_IDLE; + } setTestAlarm(type, triggerTime, pi, 0, flags, TEST_CALLING_UID); } @@ -1600,13 +1608,13 @@ public class AlarmManagerServiceTest { final long firstTrigger = mNowElapsedTest + 10; for (int i = 0; i < quota; i++) { setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent(), false); + getNewMockPendingIntent(), false, false); mNowElapsedTest = mTestTimer.getElapsed(); mTestTimer.expire(); } // This one should get deferred on set. setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, - getNewMockPendingIntent(), false); + getNewMockPendingIntent(), false, false); final long expectedNextTrigger = firstTrigger + mAllowWhileIdleWindow; assertEquals("Incorrect trigger when no quota left", expectedNextTrigger, mTestTimer.getElapsed()); @@ -1619,6 +1627,108 @@ public class AlarmManagerServiceTest { } @Test + public void allowWhileIdleCompatAlarmsWhileDeviceIdle() throws Exception { + setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0); + + final long window = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + window + 1000, + getNewMockPendingIntent()); + assertNotNull(mService.mPendingIdleUntil); + + final int quota = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; + final long firstTrigger = mNowElapsedTest + 10; + for (int i = 0; i < quota; i++) { + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, + getNewMockPendingIntent(), false, true); + mNowElapsedTest = mTestTimer.getElapsed(); + mTestTimer.expire(); + } + // This one should get deferred on set. + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + quota, + getNewMockPendingIntent(), false, true); + final long expectedNextTrigger = firstTrigger + window; + assertEquals("Incorrect trigger when no quota left", expectedNextTrigger, + mTestTimer.getElapsed()); + + // Bring the idle until alarm back. + setIdleUntilAlarm(ELAPSED_REALTIME_WAKEUP, expectedNextTrigger - 50, + getNewMockPendingIntent()); + assertEquals(expectedNextTrigger - 50, mService.mPendingIdleUntil.getWhenElapsed()); + assertEquals(expectedNextTrigger - 50, mTestTimer.getElapsed()); + } + + @Test + public void allowWhileIdleCompatHistorySeparate() throws Exception { + when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID, + TEST_CALLING_PACKAGE)).thenReturn(true); + when(mAppStateTracker.isForceAllAppsStandbyEnabled()).thenReturn(true); + + final int fullQuota = mService.mConstants.ALLOW_WHILE_IDLE_QUOTA; + final int compatQuota = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; + + final long fullWindow = mAllowWhileIdleWindow; + final long compatWindow = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + + final long firstFullTrigger = mNowElapsedTest + 10; + for (int i = 0; i < fullQuota; i++) { + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstFullTrigger + i, + getNewMockPendingIntent(), false, false); + mNowElapsedTest = mTestTimer.getElapsed(); + mTestTimer.expire(); + } + // This one should get deferred on set, as full quota is not available. + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstFullTrigger + fullQuota, + getNewMockPendingIntent(), false, false); + final long expectedNextFullTrigger = firstFullTrigger + fullWindow; + assertEquals("Incorrect trigger when no quota left", expectedNextFullTrigger, + mTestTimer.getElapsed()); + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); + + // The following should be allowed, as compat quota should be free. + for (int i = 0; i < compatQuota; i++) { + final long trigger = mNowElapsedTest + 1; + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, getNewMockPendingIntent(), + false, true); + assertEquals(trigger, mTestTimer.getElapsed()); + mNowElapsedTest = mTestTimer.getElapsed(); + mTestTimer.expire(); + } + + // Refresh the state + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); + mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + mService.mAllowWhileIdleCompatHistory.removeForPackage(TEST_CALLING_PACKAGE, + TEST_CALLING_USER); + + // Now test with flipped order + + final long firstCompatTrigger = mNowElapsedTest + 10; + for (int i = 0; i < compatQuota; i++) { + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstCompatTrigger + i, + getNewMockPendingIntent(), false, true); + mNowElapsedTest = mTestTimer.getElapsed(); + mTestTimer.expire(); + } + // This one should get deferred on set, as full quota is not available. + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstCompatTrigger + compatQuota, + getNewMockPendingIntent(), false, true); + final long expectedNextCompatTrigger = firstCompatTrigger + compatWindow; + assertEquals("Incorrect trigger when no quota left", expectedNextCompatTrigger, + mTestTimer.getElapsed()); + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); + + // The following should be allowed, as full quota should be free. + for (int i = 0; i < fullQuota; i++) { + final long trigger = mNowElapsedTest + 1; + setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, getNewMockPendingIntent(), + false, false); + assertEquals(trigger, mTestTimer.getElapsed()); + mNowElapsedTest = mTestTimer.getElapsed(); + mTestTimer.expire(); + } + } + + @Test public void allowWhileIdleUnrestricted() throws Exception { setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0); @@ -1634,7 +1744,7 @@ public class AlarmManagerServiceTest { final long firstTrigger = mNowElapsedTest + 10; for (int i = 0; i < numAlarms; i++) { setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, - getNewMockPendingIntent(), true); + getNewMockPendingIntent(), true, false); } // All of them should fire as expected. for (int i = 0; i < numAlarms; i++) { @@ -1736,7 +1846,7 @@ public class AlarmManagerServiceTest { final int quota = mService.mConstants.ALLOW_WHILE_IDLE_QUOTA; testQuotasDeferralOnSet(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, - getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow); + getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow); // Refresh the state mService.removeLocked(TEST_CALLING_UID, @@ -1744,7 +1854,7 @@ public class AlarmManagerServiceTest { mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, - trigger, getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow); + trigger, getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow); // Refresh the state mService.removeLocked(TEST_CALLING_UID, @@ -1752,7 +1862,36 @@ public class AlarmManagerServiceTest { mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, - getNewMockPendingIntent(), false), quota, mAllowWhileIdleWindow); + getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow); + } + + @Test + public void allowWhileIdleCompatAlarmsInBatterySaver() throws Exception { + when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID, + TEST_CALLING_PACKAGE)).thenReturn(true); + when(mAppStateTracker.isForceAllAppsStandbyEnabled()).thenReturn(true); + + final int quota = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; + final long window = mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; + + testQuotasDeferralOnSet(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent(), false, true), quota, window); + + // Refresh the state + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); + mService.mAllowWhileIdleCompatHistory.removeForPackage(TEST_CALLING_PACKAGE, + TEST_CALLING_USER); + + testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, + trigger, getNewMockPendingIntent(), false, true), quota, window); + + // Refresh the state + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); + mService.mAllowWhileIdleCompatHistory.removeForPackage(TEST_CALLING_PACKAGE, + TEST_CALLING_USER); + + testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent(), false, true), quota, window); } @Test @@ -2123,7 +2262,7 @@ public class AlarmManagerServiceTest { final PendingIntent alarmPi = getNewMockPendingIntent(); final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class); mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0, - alarmPi, null, null, null, alarmClock); + alarmPi, null, null, null, alarmClock); // Correct permission checks are invoked. verify(mService).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID); diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java index 1596483cdbe1..2e5c24c1a95c 100644 --- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java +++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java @@ -246,6 +246,81 @@ public class VibrationThreadTest { } @Test + public void vibrate_singleVibratorRepeatingShortAlwaysOnWaveform_turnsVibratorOnForASecond() + throws Exception { + FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID); + fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + + long vibrationId = 1; + int[] amplitudes = new int[]{1, 2, 3}; + VibrationEffect effect = VibrationEffect.createWaveform( + new long[]{1, 10, 100}, amplitudes, 0); + VibrationThread thread = startThreadAndDispatcher(vibrationId, effect); + + assertTrue(waitUntil(t -> !fakeVibrator.getAmplitudes().isEmpty(), thread, + TEST_TIMEOUT_MILLIS)); + thread.cancel(); + waitForCompletion(thread); + + verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED); + assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating()); + assertEquals(Arrays.asList(expectedOneShot(1000)), fakeVibrator.getEffectSegments()); + } + + @Test + public void vibrate_singleVibratorRepeatingLongAlwaysOnWaveform_turnsVibratorOnForACycle() + throws Exception { + FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID); + fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + + long vibrationId = 1; + int[] amplitudes = new int[]{1, 2, 3}; + VibrationEffect effect = VibrationEffect.createWaveform( + new long[]{5000, 500, 50}, amplitudes, 0); + VibrationThread thread = startThreadAndDispatcher(vibrationId, effect); + + assertTrue(waitUntil(t -> !fakeVibrator.getAmplitudes().isEmpty(), thread, + TEST_TIMEOUT_MILLIS)); + thread.cancel(); + waitForCompletion(thread); + + verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED); + assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating()); + assertEquals(Arrays.asList(expectedOneShot(5550)), fakeVibrator.getEffectSegments()); + } + + + @Test + public void vibrate_singleVibratorRepeatingAlwaysOnWaveform_turnsVibratorBackOn() + throws Exception { + FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID); + fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + + long vibrationId = 1; + int[] amplitudes = new int[]{1, 2}; + VibrationEffect effect = VibrationEffect.createWaveform( + new long[]{900, 50}, amplitudes, 0); + VibrationThread thread = startThreadAndDispatcher(vibrationId, effect); + + assertTrue(waitUntil(t -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length, + thread, 1000 + TEST_TIMEOUT_MILLIS)); + thread.cancel(); + waitForCompletion(thread); + + verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED); + assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating()); + assertEquals(2, fakeVibrator.getEffectSegments().size()); + // First time turn vibrator ON for minimum of 1s. + assertEquals(1000L, fakeVibrator.getEffectSegments().get(0).getDuration()); + // Vibrator turns off in the middle of the second execution of first step, turn it back ON + // for another 1s + remaining of 850ms. + assertEquals(1850, fakeVibrator.getEffectSegments().get(1).getDuration(), /* delta= */ 20); + // Set amplitudes for a cycle {1, 2}, start second loop then turn it back on to same value. + assertEquals(expectedAmplitudes(1, 2, 1, 1), + mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().subList(0, 4)); + } + + @Test public void vibrate_singleVibratorPredefinedCancel_cancelsVibrationImmediately() throws Exception { mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java index d0bf63a1680f..733d3f0f66ef 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java @@ -281,6 +281,34 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertNull(fromXml.pkg); } + @Test + public void testRuleXml_getPkg_nullPkg() throws Exception { + String tag = "tag"; + + ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule(); + rule.enabled = true; + rule.configurationActivity = new ComponentName("a", "a"); + + TypedXmlSerializer out = Xml.newFastSerializer(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + out.setOutput(new BufferedOutputStream(baos), "utf-8"); + out.startDocument(null, true); + out.startTag(null, tag); + ZenModeConfig.writeRuleXml(rule, out); + out.endTag(null, tag); + out.endDocument(); + + TypedXmlPullParser parser = Xml.newFastPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(baos.toByteArray())), null); + parser.nextTag(); + ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser); + assertEquals("a", fromXml.getPkg()); + + fromXml.condition = new Condition(Uri.EMPTY, "", Condition.STATE_TRUE); + assertTrue(fromXml.isAutomaticActive()); + } + private ZenModeConfig getMutedRingerConfig() { ZenModeConfig config = new ZenModeConfig(); // Allow alarms, media diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 00dbaf649ca2..4410404b0cd7 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -33,6 +33,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; +import static android.service.notification.Condition.STATE_TRUE; import static android.util.StatsLog.ANNOTATION_ID_IS_UID; import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; @@ -49,6 +50,7 @@ import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -64,6 +66,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.AutomaticZenRule; @@ -72,7 +76,9 @@ import android.app.NotificationManager.Policy; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.media.AudioAttributes; @@ -81,6 +87,7 @@ import android.media.AudioManagerInternal; import android.media.AudioSystem; import android.media.VolumePolicy; import android.net.Uri; +import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.provider.Settings; @@ -105,6 +112,8 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.server.UiServiceTestCase; import com.android.server.notification.ManagedServices.UserProfiles; +import com.google.common.collect.ImmutableList; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -172,8 +181,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(), mConditionProviders, mStatsEventBuilderFactory)); + ResolveInfo ri = new ResolveInfo(); + ri.activityInfo = new ActivityInfo(); + when(mPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt())).thenReturn( + ImmutableList.of(ri)); when(mPackageManager.getPackageUidAsUser(eq(CUSTOM_PKG_NAME), anyInt())) .thenReturn(CUSTOM_PKG_UID); + when(mPackageManager.getPackagesForUid(anyInt())).thenReturn( + new String[] {getContext().getPackageName()}); mZenModeHelperSpy.mPm = mPackageManager; } @@ -1486,7 +1501,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("android", CountdownConditionProvider.class.getName()); mZenModeHelperSpy.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0, - Condition.STATE_TRUE, Condition.FLAG_RELEVANT_NOW); + STATE_TRUE, Condition.FLAG_RELEVANT_NOW); mZenModeHelperSpy.mConfig.manualRule.enabled = true; ZenModeConfig originalConfig = mZenModeHelperSpy.mConfig.copy(); @@ -1592,10 +1607,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { } @Test - public void testAddAutomaticZenRule() { + public void testAddAutomaticZenRule_CA() { AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, new ComponentName("android", "ScheduleConditionProvider"), ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test"); @@ -1608,6 +1625,107 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(NotificationManager.zenModeFromInterruptionFilter( zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode); assertEquals(zenRule.getName(), ruleInConfig.name); + assertEquals("android", ruleInConfig.pkg); + } + + @Test + public void testAddAutomaticZenRule_CPS() { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + new ComponentName("android", "ScheduleConditionProvider"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test"); + + assertTrue(id != null); + ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id); + assertTrue(ruleInConfig != null); + assertEquals(zenRule.isEnabled(), ruleInConfig.enabled); + assertEquals(zenRule.isModified(), ruleInConfig.modified); + assertEquals(zenRule.getConditionId(), ruleInConfig.conditionId); + assertEquals(NotificationManager.zenModeFromInterruptionFilter( + zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode); + assertEquals(zenRule.getName(), ruleInConfig.name); + assertEquals("android", ruleInConfig.pkg); + } + + @Test + public void testSetAutomaticZenRuleState_nullPkg() { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, + new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + + String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test"); + mZenModeHelperSpy.setAutomaticZenRuleState(zenRule.getConditionId(), + new Condition(zenRule.getConditionId(), "", STATE_TRUE)); + + ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id); + assertEquals(STATE_TRUE, ruleInConfig.condition.state); + } + + @Test + public void testUpdateAutomaticZenRule_nullPkg() { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, + new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + + String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test"); + + AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW", + null, + new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + + mZenModeHelperSpy.updateAutomaticZenRule(id, zenRule2, ""); + + ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id); + assertEquals("NEW", ruleInConfig.name); + } + + @Test + public void testRemoveAutomaticZenRule_nullPkg() { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, + new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + + String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test"); + + assertTrue(id != null); + ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id); + assertTrue(ruleInConfig != null); + assertEquals(zenRule.getName(), ruleInConfig.name); + + mZenModeHelperSpy.removeAutomaticZenRule(id, "test"); + assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id)); + } + + @Test + public void testRemoveAutomaticZenRules_nullPkg() { + AutomaticZenRule zenRule = new AutomaticZenRule("name", + null, + new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"), + ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), + new ZenPolicy.Builder().build(), + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test"); + + assertTrue(id != null); + ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id); + assertTrue(ruleInConfig != null); + assertEquals(zenRule.getName(), ruleInConfig.name); + + mZenModeHelperSpy.removeAutomaticZenRules(mContext.getPackageName(), "test"); + assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id)); } @Test @@ -1624,17 +1742,17 @@ public class ZenModeHelperTest extends UiServiceTestCase { NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule2, "test"); - Condition condition = new Condition(sharedUri, "", Condition.STATE_TRUE); + Condition condition = new Condition(sharedUri, "", STATE_TRUE); mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition); for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) { if (rule.id.equals(id)) { assertNotNull(rule.condition); - assertTrue(rule.condition.state == Condition.STATE_TRUE); + assertTrue(rule.condition.state == STATE_TRUE); } if (rule.id.equals(id2)) { assertNotNull(rule.condition); - assertTrue(rule.condition.state == Condition.STATE_TRUE); + assertTrue(rule.condition.state == STATE_TRUE); } } |