diff options
491 files changed, 5867 insertions, 3130 deletions
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java index 1d3b5e2aa4ee..482f456b5d83 100644 --- a/core/java/android/app/ActivityClient.java +++ b/core/java/android/app/ActivityClient.java @@ -227,6 +227,18 @@ public class ActivityClient { } /** + * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not + * found. + */ + public int getTaskWindowingMode(IBinder activityToken) { + try { + return getActivityClientController().getTaskWindowingMode(activityToken); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns the non-finishing activity token below in the same task if it belongs to the same * process. */ diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index d6441a2b629b..4fc3254ed1a3 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -1149,7 +1149,6 @@ public class ActivityOptions extends ComponentOptions { opts.mLaunchIntoPipParams = new PictureInPictureParams.Builder(pictureInPictureParams) .setIsLaunchIntoPip(true) .build(); - opts.mLaunchBounds = new Rect(pictureInPictureParams.getSourceRectHint()); return opts; } diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java index 877e7d3b3bf7..57dacd024ba1 100644 --- a/core/java/android/app/ActivityTransitionState.java +++ b/core/java/android/app/ActivityTransitionState.java @@ -263,6 +263,11 @@ class ActivityTransitionState { // After orientation change, the onResume can come in before the top Activity has // left, so if the Activity is not top, wait a second for the top Activity to exit. if (mEnterTransitionCoordinator == null || activity.isTopOfTask()) { + if (mEnterTransitionCoordinator != null) { + mEnterTransitionCoordinator.runAfterTransitionsComplete(() -> { + mEnterTransitionCoordinator = null; + }); + } restoreExitedViews(); restoreReenteringViews(); } else { @@ -271,6 +276,11 @@ class ActivityTransitionState { public void run() { if (mEnterTransitionCoordinator == null || mEnterTransitionCoordinator.isWaitingForRemoteExit()) { + if (mEnterTransitionCoordinator != null) { + mEnterTransitionCoordinator.runAfterTransitionsComplete(() -> { + mEnterTransitionCoordinator = null; + }); + } restoreExitedViews(); restoreReenteringViews(); } else if (mEnterTransitionCoordinator.isReturning()) { diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl index 7aeb2b26dd15..f5e5cda9c639 100644 --- a/core/java/android/app/IActivityClientController.aidl +++ b/core/java/android/app/IActivityClientController.aidl @@ -78,6 +78,7 @@ interface IActivityClientController { boolean willActivityBeVisible(in IBinder token); int getDisplayId(in IBinder activityToken); int getTaskForActivity(in IBinder token, in boolean onlyRoot); + int getTaskWindowingMode(in IBinder activityToken); IBinder getActivityTokenBelow(IBinder token); ComponentName getCallingActivity(in IBinder token); String getCallingPackage(in IBinder token); diff --git a/core/java/android/app/search/SearchAction.java b/core/java/android/app/search/SearchAction.java index 9e40e7ebaef0..0c4508a4fb8d 100644 --- a/core/java/android/app/search/SearchAction.java +++ b/core/java/android/app/search/SearchAction.java @@ -67,7 +67,7 @@ public final class SearchAction implements Parcelable { private final UserHandle mUserHandle; @Nullable - private Bundle mExtras; + private final Bundle mExtras; SearchAction(Parcel in) { mId = in.readString(); @@ -99,7 +99,7 @@ public final class SearchAction implements Parcelable { mPendingIntent = pendingIntent; mIntent = intent; mUserHandle = userHandle; - mExtras = extras; + mExtras = extras != null ? extras : new Bundle(); if (mPendingIntent == null && mIntent == null) { throw new IllegalStateException("At least one type of intent should be available."); diff --git a/core/java/android/app/search/SearchTarget.java b/core/java/android/app/search/SearchTarget.java index a590a5d7b767..a3874f7cb007 100644 --- a/core/java/android/app/search/SearchTarget.java +++ b/core/java/android/app/search/SearchTarget.java @@ -185,7 +185,7 @@ public final class SearchTarget implements Parcelable { mShortcutInfo = shortcutInfo; mAppWidgetProviderInfo = appWidgetProviderInfo; mSliceUri = sliceUri; - mExtras = extras; + mExtras = extras != null ? extras : new Bundle(); int published = 0; if (mSearchAction != null) published++; diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 18c638112480..a432b8dec2cb 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -1130,7 +1130,9 @@ public class AppWidgetManager { * @param intent The intent of the service which will be providing the data to the * RemoteViewsAdapter. * @param connection The callback interface to be notified when a connection is made or lost. - * @param flags Flags used for binding to the service + * @param flags Flags used for binding to the service. Currently only + * {@link Context#BIND_AUTO_CREATE} and + * {@link Context#BIND_FOREGROUND_SERVICE_WHILE_AWAKE} are supported. * * @see Context#getServiceDispatcher(ServiceConnection, Handler, int) * @hide diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java index e8e4fc988937..f2525d17e30a 100644 --- a/core/java/android/hardware/radio/ProgramList.java +++ b/core/java/android/hardware/radio/ProgramList.java @@ -22,10 +22,11 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import android.util.ArrayMap; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -41,7 +42,7 @@ public final class ProgramList implements AutoCloseable { private final Object mLock = new Object(); private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mPrograms = - new HashMap<>(); + new ArrayMap<>(); private final List<ListCallback> mListCallbacks = new ArrayList<>(); private final List<OnCompleteListener> mOnCompleteListeners = new ArrayList<>(); @@ -184,8 +185,14 @@ public final class ProgramList implements AutoCloseable { listCallbacksCopied = new ArrayList<>(mListCallbacks); if (chunk.isPurge()) { - for (ProgramSelector.Identifier id : mPrograms.keySet()) { - removeLocked(id, removedList); + Iterator<Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo>> + programsIterator = mPrograms.entrySet().iterator(); + while (programsIterator.hasNext()) { + RadioManager.ProgramInfo removed = programsIterator.next().getValue(); + if (removed != null) { + removedList.add(removed.getSelector().getPrimaryId()); + } + programsIterator.remove(); } } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index ac4c2ea448ac..d37756551db3 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -404,7 +404,7 @@ public final class WindowManagerGlobal { try { root.setView(view, wparams, panelParentView, userId); } catch (RuntimeException e) { - final int viewIndex = findViewLocked(view, false); + final int viewIndex = (index >= 0) ? index : (mViews.size() - 1); // BadTokenException or InvalidDisplayException, clean up. if (viewIndex >= 0) { removeViewLocked(viewIndex, true); diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index c81184fb2383..1f3841ad8b58 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -110,8 +110,11 @@ public final class TransitionInfo implements Parcelable { /** The container is an input-method window. */ public static final int FLAG_IS_INPUT_METHOD = 1 << 8; + /** The container is ActivityEmbedding embedded. */ + public static final int FLAG_IS_EMBEDDED = 1 << 9; + /** The first unused bit. This can be used by remotes to attach custom flags to this change. */ - public static final int FLAG_FIRST_CUSTOM = 1 << 9; + public static final int FLAG_FIRST_CUSTOM = 1 << 10; /** @hide */ @IntDef(prefix = { "FLAG_" }, value = { @@ -125,6 +128,7 @@ public final class TransitionInfo implements Parcelable { FLAG_OCCLUDES_KEYGUARD, FLAG_DISPLAY_HAS_ALERT_WINDOWS, FLAG_IS_INPUT_METHOD, + FLAG_IS_EMBEDDED, FLAG_FIRST_CUSTOM }) public @interface ChangeFlags {} @@ -325,6 +329,9 @@ public final class TransitionInfo implements Parcelable { if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) { sb.append((sb.length() == 0 ? "" : "|") + "DISPLAY_HAS_ALERT_WINDOWS"); } + if ((flags & FLAG_IS_EMBEDDED) != 0) { + sb.append((sb.length() == 0 ? "" : "|") + "IS_EMBEDDED"); + } if ((flags & FLAG_FIRST_CUSTOM) != 0) { sb.append((sb.length() == 0 ? "" : "|") + "FIRST_CUSTOM"); } diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java index 737d5e348249..b32afb44852a 100644 --- a/core/java/com/android/internal/app/ResolverListAdapter.java +++ b/core/java/com/android/internal/app/ResolverListAdapter.java @@ -417,8 +417,9 @@ public class ResolverListAdapter extends BaseAdapter { if (ii == null) { continue; } - ActivityInfo ai = ii.resolveActivityInfo( - mPm, 0); + // Because of AIDL bug, resolveActivityInfo can't accept subclasses of Intent. + final Intent rii = (ii.getClass() == Intent.class) ? ii : new Intent(ii); + ActivityInfo ai = rii.resolveActivityInfo(mPm, 0); if (ai == null) { Log.w(TAG, "No activity found for " + ii); continue; diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 100fcd817812..01dcf9624ed5 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -136,12 +136,15 @@ public class ResolverListController { int baseFlags) { List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null; for (int i = 0, N = intents.size(); i < N; i++) { - final Intent intent = intents.get(i); + Intent intent = intents.get(i); int flags = baseFlags; if (intent.isWebIntent() || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) { flags |= PackageManager.MATCH_INSTANT; } + // Because of AIDL bug, queryIntentActivitiesAsUser can't accept subclasses of Intent. + intent = (intent.getClass() == Intent.class) ? intent : new Intent( + intent); final List<ResolveInfo> infos = mpm.queryIntentActivitiesAsUser(intent, flags, userHandle); if (infos != null) { diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java index 825b486d0635..dbfa4d35974b 100644 --- a/core/java/com/android/internal/jank/FrameTracker.java +++ b/core/java/com/android/internal/jank/FrameTracker.java @@ -26,10 +26,12 @@ import static android.view.SurfaceControl.JankData.SURFACE_FLINGER_SCHEDULING; import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_CANCEL; import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_END; +import static com.android.internal.jank.InteractionJankMonitor.EXECUTOR_TASK_TIMEOUT; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UiThread; import android.graphics.HardwareRendererObserver; import android.os.Handler; import android.os.Trace; @@ -85,8 +87,9 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener public @interface Reasons { } + @VisibleForTesting + public final InteractionJankMonitor mMonitor; private final HardwareRendererObserver mObserver; - private SurfaceControl mSurfaceControl; private final int mTraceThresholdMissedFrames; private final int mTraceThresholdFrameTimeMillis; private final ThreadedRendererWrapper mRendererWrapper; @@ -99,17 +102,17 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener private final Handler mHandler; private final ChoreographerWrapper mChoreographer; private final StatsLogWrapper mStatsLog; - private final Object mLock = InteractionJankMonitor.getInstance().getLock(); private final boolean mDeferMonitoring; + private final FrameTrackerListener mListener; @VisibleForTesting public final boolean mSurfaceOnly; + private SurfaceControl mSurfaceControl; private long mBeginVsyncId = INVALID_ID; private long mEndVsyncId = INVALID_ID; private boolean mMetricsFinalized; private boolean mCancelled = false; - private FrameTrackerListener mListener; private boolean mTracingStarted = false; private Runnable mWaitForFinishTimedOut; @@ -142,16 +145,52 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener this.jankType = jankType; this.isFirstFrame = isFirstFrame; } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + switch (jankType) { + case JANK_NONE: + str.append("JANK_NONE"); + break; + case JANK_APP_DEADLINE_MISSED: + str.append("JANK_APP_DEADLINE_MISSED"); + break; + case JANK_SURFACEFLINGER_DEADLINE_MISSED: + str.append("JANK_SURFACEFLINGER_DEADLINE_MISSED"); + break; + case JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED: + str.append("JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED"); + break; + case DISPLAY_HAL: + str.append("DISPLAY_HAL"); + break; + case PREDICTION_ERROR: + str.append("PREDICTION_ERROR"); + break; + case SURFACE_FLINGER_SCHEDULING: + str.append("SURFACE_FLINGER_SCHEDULING"); + break; + default: + str.append("UNKNOWN: ").append(jankType); + break; + } + str.append(", ").append(frameVsyncId); + str.append(", ").append(totalDurationNanos); + return str.toString(); + } } - public FrameTracker(@NonNull Session session, @NonNull Handler handler, - @Nullable ThreadedRendererWrapper renderer, @Nullable ViewRootWrapper viewRootWrapper, + public FrameTracker(@NonNull InteractionJankMonitor monitor, @NonNull Session session, + @NonNull Handler handler, @Nullable ThreadedRendererWrapper renderer, + @Nullable ViewRootWrapper viewRootWrapper, @NonNull SurfaceControlWrapper surfaceControlWrapper, @NonNull ChoreographerWrapper choreographer, @Nullable FrameMetricsWrapper metrics, @NonNull StatsLogWrapper statsLog, int traceThresholdMissedFrames, int traceThresholdFrameTimeMillis, @Nullable FrameTrackerListener listener, @NonNull Configuration config) { + mMonitor = monitor; mSurfaceOnly = config.isSurfaceOnly(); mSession = session; mHandler = handler; @@ -186,17 +225,15 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mSurfaceChangedCallback = new ViewRootImpl.SurfaceChangedCallback() { @Override public void surfaceCreated(SurfaceControl.Transaction t) { - synchronized (mLock) { + getHandler().runWithScissors(() -> { if (mSurfaceControl == null) { mSurfaceControl = mViewRoot.getSurfaceControl(); if (mBeginVsyncId != INVALID_ID) { - mSurfaceControlWrapper.addJankStatsListener( - FrameTracker.this, mSurfaceControl); - markEvent("FT#deferMonitoring"); - postTraceStartMarker(); + // Previous begin invocation is not successfully, begin it again. + begin(); } } - } + }, EXECUTOR_TASK_TIMEOUT); } @Override @@ -208,18 +245,16 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener // Wait a while to give the system a chance for the remaining // frames to arrive, then force finish the session. - mHandler.postDelayed(() -> { - synchronized (mLock) { - if (DEBUG) { - Log.d(TAG, "surfaceDestroyed: " + mSession.getName() - + ", finalized=" + mMetricsFinalized - + ", info=" + mJankInfos.size() - + ", vsync=" + mBeginVsyncId); - } - if (!mMetricsFinalized) { - end(REASON_END_SURFACE_DESTROYED); - finish(); - } + getHandler().postDelayed(() -> { + if (DEBUG) { + Log.d(TAG, "surfaceDestroyed: " + mSession.getName() + + ", finalized=" + mMetricsFinalized + + ", info=" + mJankInfos.size() + + ", vsync=" + mBeginVsyncId); + } + if (!mMetricsFinalized) { + end(REASON_END_SURFACE_DESTROYED); + finish(); } }, 50); } @@ -230,35 +265,42 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener } } + @VisibleForTesting + public Handler getHandler() { + return mHandler; + } + /** * Begin a trace session of the CUJ. */ + @UiThread public void begin() { - synchronized (mLock) { - final long currentVsync = mChoreographer.getVsyncId(); - // In normal case, we should begin at the next frame, - // the id of the next frame is not simply increased by 1, - // but we can exclude the current frame at least. + final long currentVsync = mChoreographer.getVsyncId(); + // In normal case, we should begin at the next frame, + // the id of the next frame is not simply increased by 1, + // but we can exclude the current frame at least. + if (mBeginVsyncId == INVALID_ID) { mBeginVsyncId = mDeferMonitoring ? currentVsync + 1 : currentVsync; + } + if (mSurfaceControl != null) { if (DEBUG) { Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId - + ", defer=" + mDeferMonitoring); + + ", defer=" + mDeferMonitoring + ", current=" + currentVsync); } - if (mSurfaceControl != null) { - if (mDeferMonitoring) { - markEvent("FT#deferMonitoring"); - // Normal case, we begin the instrument from the very beginning, - // will exclude the first frame. - postTraceStartMarker(); - } else { - // If we don't begin the instrument from the very beginning, - // there is no need to skip the frame where the begin invocation happens. - beginInternal(); - } - mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl); + if (mDeferMonitoring && currentVsync < mBeginVsyncId) { + markEvent("FT#deferMonitoring"); + // Normal case, we begin the instrument from the very beginning, + // will exclude the first frame. + postTraceStartMarker(this::beginInternal); + } else { + // If we don't begin the instrument from the very beginning, + // there is no need to skip the frame where the begin invocation happens. + beginInternal(); } - if (!mSurfaceOnly) { - mRendererWrapper.addObserver(mObserver); + } else { + if (DEBUG) { + Log.d(TAG, "begin: defer beginning since the surface is not ready for CUJ=" + + mSession.getName()); } } } @@ -267,89 +309,89 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener * Start trace section at appropriate time. */ @VisibleForTesting - public void postTraceStartMarker() { - mChoreographer.mChoreographer.postCallback( - Choreographer.CALLBACK_INPUT, this::beginInternal, null); + public void postTraceStartMarker(Runnable action) { + mChoreographer.mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, action, null); } + @UiThread private void beginInternal() { - synchronized (mLock) { - if (mCancelled || mEndVsyncId != INVALID_ID) { - return; - } - mTracingStarted = true; - markEvent("FT#begin"); - Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId); + if (mCancelled || mEndVsyncId != INVALID_ID) { + return; + } + mTracingStarted = true; + markEvent("FT#begin"); + Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId); + mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl); + if (!mSurfaceOnly) { + mRendererWrapper.addObserver(mObserver); } } /** * End the trace session of the CUJ. */ + @UiThread public boolean end(@Reasons int reason) { - synchronized (mLock) { - if (mCancelled || mEndVsyncId != INVALID_ID) return false; - mEndVsyncId = mChoreographer.getVsyncId(); - // Cancel the session if: - // 1. The session begins and ends at the same vsync id. - // 2. The session never begun. - if (mBeginVsyncId == INVALID_ID) { - return cancel(REASON_CANCEL_NOT_BEGUN); - } else if (mEndVsyncId <= mBeginVsyncId) { - return cancel(REASON_CANCEL_SAME_VSYNC); - } else { - if (DEBUG) { - Log.d(TAG, "end: " + mSession.getName() - + ", end=" + mEndVsyncId + ", reason=" + reason); - } - markEvent("FT#end#" + reason); - Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId); - mSession.setReason(reason); - - // We don't remove observer here, - // will remove it when all the frame metrics in this duration are called back. - // See onFrameMetricsAvailable for the logic of removing the observer. - // Waiting at most 10 seconds for all callbacks to finish. - mWaitForFinishTimedOut = () -> { - Log.e(TAG, "force finish cuj because of time out:" + mSession.getName()); - finish(); - }; - mHandler.postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10)); - notifyCujEvent(ACTION_SESSION_END); - return true; + if (mCancelled || mEndVsyncId != INVALID_ID) return false; + mEndVsyncId = mChoreographer.getVsyncId(); + // Cancel the session if: + // 1. The session begins and ends at the same vsync id. + // 2. The session never begun. + if (mBeginVsyncId == INVALID_ID) { + return cancel(REASON_CANCEL_NOT_BEGUN); + } else if (mEndVsyncId <= mBeginVsyncId) { + return cancel(REASON_CANCEL_SAME_VSYNC); + } else { + if (DEBUG) { + Log.d(TAG, "end: " + mSession.getName() + + ", end=" + mEndVsyncId + ", reason=" + reason); } + markEvent("FT#end#" + reason); + Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId); + mSession.setReason(reason); + + // We don't remove observer here, + // will remove it when all the frame metrics in this duration are called back. + // See onFrameMetricsAvailable for the logic of removing the observer. + // Waiting at most 10 seconds for all callbacks to finish. + mWaitForFinishTimedOut = () -> { + Log.e(TAG, "force finish cuj because of time out:" + mSession.getName()); + finish(); + }; + getHandler().postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10)); + notifyCujEvent(ACTION_SESSION_END); + return true; } } /** * Cancel the trace session of the CUJ. */ + @UiThread public boolean cancel(@Reasons int reason) { - synchronized (mLock) { - final boolean cancelFromEnd = - reason == REASON_CANCEL_NOT_BEGUN || reason == REASON_CANCEL_SAME_VSYNC; - if (mCancelled || (mEndVsyncId != INVALID_ID && !cancelFromEnd)) return false; - mCancelled = true; - markEvent("FT#cancel#" + reason); - // We don't need to end the trace section if it never begun. - if (mTracingStarted) { - Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId); - } - - // Always remove the observers in cancel call to avoid leakage. - removeObservers(); + final boolean cancelFromEnd = + reason == REASON_CANCEL_NOT_BEGUN || reason == REASON_CANCEL_SAME_VSYNC; + if (mCancelled || (mEndVsyncId != INVALID_ID && !cancelFromEnd)) return false; + mCancelled = true; + markEvent("FT#cancel#" + reason); + // We don't need to end the trace section if it has never begun. + if (mTracingStarted) { + Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId); + } - if (DEBUG) { - Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId - + ", end=" + mEndVsyncId + ", reason=" + reason); - } + // Always remove the observers in cancel call to avoid leakage. + removeObservers(); - mSession.setReason(reason); - // Notify the listener the session has been cancelled. - // We don't notify the listeners if the session never begun. - notifyCujEvent(ACTION_SESSION_CANCEL); - return true; + if (DEBUG) { + Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId + + ", end=" + mEndVsyncId + ", reason=" + reason); } + + mSession.setReason(reason); + // Notify the listener the session has been cancelled. + // We don't notify the listeners if the session never begun. + notifyCujEvent(ACTION_SESSION_CANCEL); + return true; } private void markEvent(String desc) { @@ -364,8 +406,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener @Override public void onJankDataAvailable(SurfaceControl.JankData[] jankData) { - synchronized (mLock) { - if (mCancelled) { + postCallback(() -> { + if (mCancelled || mMetricsFinalized) { return; } @@ -384,10 +426,19 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener } } processJankInfos(); - } + }); } - private @Nullable JankInfo findJankInfo(long frameVsyncId) { + /** + * For easier argument capture. + */ + @VisibleForTesting + public void postCallback(Runnable callback) { + getHandler().post(callback); + } + + @Nullable + private JankInfo findJankInfo(long frameVsyncId) { return mJankInfos.get((int) frameVsyncId); } @@ -400,8 +451,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener @Override public void onFrameMetricsAvailable(int dropCountSinceLastInvocation) { - synchronized (mLock) { - if (mCancelled) { + postCallback(() -> { + if (mCancelled || mMetricsFinalized) { return; } @@ -426,9 +477,10 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener frameVsyncId, totalDurationNanos, isFirstFrame)); } processJankInfos(); - } + }); } + @UiThread private boolean hasReceivedCallbacksAfterEnd() { if (mEndVsyncId == INVALID_ID) { return false; @@ -451,6 +503,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener return false; } + @UiThread private void processJankInfos() { if (mMetricsFinalized) { return; @@ -467,9 +520,12 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener : info.hwuiCallbackFired && info.surfaceControlCallbackFired; } + @UiThread private void finish() { - mHandler.removeCallbacks(mWaitForFinishTimedOut); + getHandler().removeCallbacks(mWaitForFinishTimedOut); mWaitForFinishTimedOut = null; + if (mMetricsFinalized || mCancelled) return; + markEvent("FT#finish#" + mJankInfos.size()); mMetricsFinalized = true; // The tracing has been ended, remove the observer, see if need to trigger perfetto. @@ -496,7 +552,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener totalFramesCount++; boolean missedFrame = false; if ((info.jankType & JANK_APP_DEADLINE_MISSED) != 0) { - Log.w(TAG, "Missed App frame:" + info.jankType); + Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + mSession.getName()); missedAppFramesCount++; missedFrame = true; } @@ -505,7 +561,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener || (info.jankType & JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED) != 0 || (info.jankType & SURFACE_FLINGER_SCHEDULING) != 0 || (info.jankType & PREDICTION_ERROR) != 0) { - Log.w(TAG, "Missed SF frame:" + info.jankType); + Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + mSession.getName()); missedSfFramesCount++; missedFrame = true; } @@ -520,13 +576,15 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener // TODO (b/174755489): Early latch currently gets fired way too often, so we have // to ignore it for now. if (!mSurfaceOnly && !info.hwuiCallbackFired) { - Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId); + Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId + + ", CUJ=" + mSession.getName()); } } if (!mSurfaceOnly && info.hwuiCallbackFired) { maxFrameTimeNanos = Math.max(info.totalDurationNanos, maxFrameTimeNanos); if (!info.surfaceControlCallbackFired) { - Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId); + Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId + + ", CUJ=" + mSession.getName()); } } } @@ -586,6 +644,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener * Remove all the registered listeners, observers and callbacks. */ @VisibleForTesting + @UiThread public void removeObservers() { mSurfaceControlWrapper.removeJankStatsListener(this); if (!mSurfaceOnly) { @@ -601,7 +660,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener * Trigger the prefetto daemon. */ public void triggerPerfetto() { - InteractionJankMonitor.getInstance().trigger(mSession); + mMonitor.trigger(mSession); } /** @@ -666,10 +725,18 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mViewRoot = viewRoot; } + /** + * {@link ViewRootImpl#addSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback)} + * @param callback {@link ViewRootImpl.SurfaceChangedCallback} + */ public void addSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback callback) { mViewRoot.addSurfaceChangedCallback(callback); } + /** + * {@link ViewRootImpl#removeSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback)} + * @param callback {@link ViewRootImpl.SurfaceChangedCallback} + */ public void removeSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback callback) { mViewRoot.removeSurfaceChangedCallback(callback); } diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 22340c6b0c55..8f10a5e3f049 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -53,6 +53,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_COLLAPSE_LOCK; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR; @@ -85,8 +86,11 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.UiThread; +import android.annotation.WorkerThread; import android.content.Context; import android.os.Build; +import android.os.Handler; import android.os.HandlerExecutor; import android.os.HandlerThread; import android.provider.DeviceConfig; @@ -97,6 +101,7 @@ import android.view.Choreographer; import android.view.SurfaceControl; import android.view.View; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.FrameTracker.ChoreographerWrapper; import com.android.internal.jank.FrameTracker.FrameMetricsWrapper; @@ -130,6 +135,7 @@ public class InteractionJankMonitor { private static final String DEFAULT_WORKER_NAME = TAG + "-Worker"; private static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2L); + static final long EXECUTOR_TASK_TIMEOUT = 500; private static final String SETTINGS_ENABLED_KEY = "enabled"; private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval"; private static final String SETTINGS_THRESHOLD_MISSED_FRAMES_KEY = @@ -210,6 +216,7 @@ public class InteractionJankMonitor { public static final int CUJ_USER_DIALOG_OPEN = 59; public static final int CUJ_TASKBAR_EXPAND = 60; public static final int CUJ_TASKBAR_COLLAPSE = 61; + public static final int CUJ_SHADE_CLEAR_ALL = 62; private static final int NO_STATSD_LOGGING = -1; @@ -280,6 +287,7 @@ public class InteractionJankMonitor { UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL, }; private static volatile InteractionJankMonitor sInstance; @@ -287,13 +295,14 @@ public class InteractionJankMonitor { private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener = this::updateProperties; - private final FrameMetricsWrapper mMetrics; + @GuardedBy("mLock") private final SparseArray<FrameTracker> mRunningTrackers; + @GuardedBy("mLock") private final SparseArray<Runnable> mTimeoutActions; private final HandlerThread mWorker; private final Object mLock = new Object(); - private boolean mEnabled = DEFAULT_ENABLED; + private volatile boolean mEnabled = DEFAULT_ENABLED; private int mSamplingInterval = DEFAULT_SAMPLING_INTERVAL; private int mTraceThresholdMissedFrames = DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES; private int mTraceThresholdFrameTimeMillis = DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS; @@ -361,7 +370,8 @@ public class InteractionJankMonitor { CUJ_SHADE_DIALOG_OPEN, CUJ_USER_DIALOG_OPEN, CUJ_TASKBAR_EXPAND, - CUJ_TASKBAR_COLLAPSE + CUJ_TASKBAR_COLLAPSE, + CUJ_SHADE_CLEAR_ALL }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { @@ -394,9 +404,7 @@ public class InteractionJankMonitor { mRunningTrackers = new SparseArray<>(); mTimeoutActions = new SparseArray<>(); mWorker = worker; - mMetrics = new FrameMetricsWrapper(); mWorker.start(); - mEnabled = DEFAULT_ENABLED; mSamplingInterval = DEFAULT_SAMPLING_INTERVAL; // Post initialization to the background in case we're running on the main @@ -409,10 +417,7 @@ public class InteractionJankMonitor { DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR, new HandlerExecutor(mWorker.getThreadHandler()), mPropertiesChangedListener); - } - - Object getLock() { - return mLock; + mEnabled = DEFAULT_ENABLED; } /** @@ -429,27 +434,27 @@ public class InteractionJankMonitor { view == null ? null : new ThreadedRendererWrapper(view.getThreadedRenderer()); final ViewRootWrapper viewRoot = view == null ? null : new ViewRootWrapper(view.getViewRootImpl()); - final SurfaceControlWrapper surfaceControl = new SurfaceControlWrapper(); final ChoreographerWrapper choreographer = new ChoreographerWrapper(Choreographer.getInstance()); + final FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s); + final FrameMetricsWrapper frameMetrics = new FrameMetricsWrapper(); - synchronized (mLock) { - FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s); - return new FrameTracker(session, mWorker.getThreadHandler(), - threadedRenderer, viewRoot, surfaceControl, choreographer, - mMetrics, new FrameTracker.StatsLogWrapper(), - mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis, - eventsListener, config); - } + return new FrameTracker(this, session, config.getHandler(), threadedRenderer, viewRoot, + surfaceControl, choreographer, frameMetrics, new FrameTracker.StatsLogWrapper(), + mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis, + eventsListener, config); } + @UiThread private void handleCujEvents(String action, Session session) { // Clear the running and timeout tasks if the end / cancel was fired within the tracker. // Or we might have memory leaks. if (needRemoveTasks(action, session)) { - removeTimeout(session.getCuj()); - removeTracker(session.getCuj()); + getTracker(session.getCuj()).getHandler().runWithScissors(() -> { + removeTimeout(session.getCuj()); + removeTracker(session.getCuj()); + }, EXECUTOR_TASK_TIMEOUT); } } @@ -466,7 +471,7 @@ public class InteractionJankMonitor { synchronized (mLock) { Runnable timeout = mTimeoutActions.get(cujType); if (timeout != null) { - mWorker.getThreadHandler().removeCallbacks(timeout); + getTracker(cujType).getHandler().removeCallbacks(timeout); mTimeoutActions.remove(cujType); } } @@ -491,9 +496,7 @@ public class InteractionJankMonitor { */ public boolean begin(View v, @CujType int cujType) { try { - return beginInternal( - Configuration.Builder.withView(cujType, v) - .build()); + return begin(Configuration.Builder.withView(cujType, v)); } catch (IllegalArgumentException ex) { Log.d(TAG, "Build configuration failed!", ex); return false; @@ -504,35 +507,42 @@ public class InteractionJankMonitor { * Begins a trace session. * * @param builder the builder of the configurations for instrumenting the CUJ. - * @return boolean true if the tracker is started successfully, false otherwise. + * @return boolean true if the tracker is begun successfully, false otherwise. */ public boolean begin(@NonNull Configuration.Builder builder) { try { - return beginInternal(builder.build()); + final Configuration config = builder.build(); + final TrackerResult result = new TrackerResult(); + final boolean success = config.getHandler().runWithScissors( + () -> result.mResult = beginInternal(config), EXECUTOR_TASK_TIMEOUT); + if (!success) { + Log.d(TAG, "begin failed due to timeout, CUJ=" + getNameOfCuj(config.mCujType)); + return false; + } + return result.mResult; } catch (IllegalArgumentException ex) { Log.d(TAG, "Build configuration failed!", ex); return false; } } + @UiThread private boolean beginInternal(@NonNull Configuration conf) { - synchronized (mLock) { - int cujType = conf.mCujType; - if (!shouldMonitor(cujType)) return false; - FrameTracker tracker = getTracker(cujType); - // Skip subsequent calls if we already have an ongoing tracing. - if (tracker != null) return false; - - // begin a new trace session. - tracker = createFrameTracker(conf, new Session(cujType, conf.mTag)); - mRunningTrackers.put(cujType, tracker); - tracker.begin(); - - // Cancel the trace if we don't get an end() call in specified duration. - scheduleTimeoutAction( - cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT)); - return true; - } + int cujType = conf.mCujType; + if (!shouldMonitor(cujType)) return false; + FrameTracker tracker = getTracker(cujType); + // Skip subsequent calls if we already have an ongoing tracing. + if (tracker != null) return false; + + // begin a new trace session. + tracker = createFrameTracker(conf, new Session(cujType, conf.mTag)); + putTracker(cujType, tracker); + tracker.begin(); + + // Cancel the trace if we don't get an end() call in specified duration. + scheduleTimeoutAction( + cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT)); + return true; } /** @@ -561,8 +571,10 @@ public class InteractionJankMonitor { */ @VisibleForTesting public void scheduleTimeoutAction(@CujType int cuj, long timeout, Runnable action) { - mTimeoutActions.put(cuj, action); - mWorker.getThreadHandler().postDelayed(action, timeout); + synchronized (mLock) { + mTimeoutActions.put(cuj, action); + getTracker(cuj).getHandler().postDelayed(action, timeout); + } } /** @@ -572,18 +584,35 @@ public class InteractionJankMonitor { * @return boolean true if the tracker is ended successfully, false otherwise. */ public boolean end(@CujType int cujType) { - synchronized (mLock) { - // remove the timeout action first. - removeTimeout(cujType); - FrameTracker tracker = getTracker(cujType); - // Skip this call since we haven't started a trace yet. - if (tracker == null) return false; - // if the end call doesn't return true, another thread is handling end of the cuj. - if (tracker.end(REASON_END_NORMAL)) { - removeTracker(cujType); + FrameTracker tracker = getTracker(cujType); + // Skip this call since we haven't started a trace yet. + if (tracker == null) return false; + try { + final TrackerResult result = new TrackerResult(); + final boolean success = tracker.getHandler().runWithScissors( + () -> result.mResult = endInternal(cujType), EXECUTOR_TASK_TIMEOUT); + if (!success) { + Log.d(TAG, "end failed due to timeout, CUJ=" + getNameOfCuj(cujType)); + return false; } - return true; + return result.mResult; + } catch (IllegalArgumentException ex) { + Log.d(TAG, "Execute end task failed!", ex); + return false; + } + } + + @UiThread + private boolean endInternal(@CujType int cujType) { + // remove the timeout action first. + removeTimeout(cujType); + FrameTracker tracker = getTracker(cujType); + if (tracker == null) return false; + // if the end call doesn't return true, another thread is handling end of the cuj. + if (tracker.end(REASON_END_NORMAL)) { + removeTracker(cujType); } + return true; } /** @@ -602,39 +631,66 @@ public class InteractionJankMonitor { */ @VisibleForTesting public boolean cancel(@CujType int cujType, @Reasons int reason) { - synchronized (mLock) { - // remove the timeout action first. - removeTimeout(cujType); - FrameTracker tracker = getTracker(cujType); - // Skip this call since we haven't started a trace yet. - if (tracker == null) return false; - // if the cancel call doesn't return true, another thread is handling cancel of the cuj. - if (tracker.cancel(reason)) { - removeTracker(cujType); + FrameTracker tracker = getTracker(cujType); + // Skip this call since we haven't started a trace yet. + if (tracker == null) return false; + try { + final TrackerResult result = new TrackerResult(); + final boolean success = tracker.getHandler().runWithScissors( + () -> result.mResult = cancelInternal(cujType, reason), EXECUTOR_TASK_TIMEOUT); + if (!success) { + Log.d(TAG, "cancel failed due to timeout, CUJ=" + getNameOfCuj(cujType)); + return false; } - return true; + return result.mResult; + } catch (IllegalArgumentException ex) { + Log.d(TAG, "Execute cancel task failed!", ex); + return false; + } + } + + @UiThread + private boolean cancelInternal(@CujType int cujType, @Reasons int reason) { + // remove the timeout action first. + removeTimeout(cujType); + FrameTracker tracker = getTracker(cujType); + if (tracker == null) return false; + // if the cancel call doesn't return true, another thread is handling cancel of the cuj. + if (tracker.cancel(reason)) { + removeTracker(cujType); + } + return true; + } + + private void putTracker(@CujType int cuj, @NonNull FrameTracker tracker) { + synchronized (mLock) { + mRunningTrackers.put(cuj, tracker); } } private FrameTracker getTracker(@CujType int cuj) { - return mRunningTrackers.get(cuj); + synchronized (mLock) { + return mRunningTrackers.get(cuj); + } } private void removeTracker(@CujType int cuj) { - mRunningTrackers.remove(cuj); + synchronized (mLock) { + mRunningTrackers.remove(cuj); + } } + @WorkerThread private void updateProperties(DeviceConfig.Properties properties) { - synchronized (mLock) { - mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, - DEFAULT_SAMPLING_INTERVAL); - mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); - mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY, - DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES); - mTraceThresholdFrameTimeMillis = properties.getInt( - SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY, - DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS); - } + mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, + DEFAULT_SAMPLING_INTERVAL); + mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY, + DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES); + mTraceThresholdFrameTimeMillis = properties.getInt( + SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY, + DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS); + // The memory visibility is powered by the volatile field, mEnabled. + mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); } @VisibleForTesting @@ -804,10 +860,16 @@ public class InteractionJankMonitor { return "TASKBAR_EXPAND"; case CUJ_TASKBAR_COLLAPSE: return "TASKBAR_COLLAPSE"; + case CUJ_SHADE_CLEAR_ALL: + return "SHADE_CLEAR_ALL"; } return "UNKNOWN"; } + private static class TrackerResult { + private boolean mResult; + } + /** * Configurations used while instrumenting the CUJ. <br/> * <b>It may refer to an attached view, don't use static reference for any purpose.</b> @@ -821,6 +883,7 @@ public class InteractionJankMonitor { private final SurfaceControl mSurfaceControl; private final @CujType int mCujType; private final boolean mDeferMonitor; + private final Handler mHandler; /** * A builder for building Configuration. {@link #setView(View)} is essential @@ -964,6 +1027,7 @@ public class InteractionJankMonitor { mSurfaceControl = surfaceControl; mDeferMonitor = deferMonitor; validate(); + mHandler = mSurfaceOnly ? mContext.getMainThreadHandler() : mView.getHandler(); } private void validate() { @@ -1012,20 +1076,25 @@ public class InteractionJankMonitor { return mSurfaceControl; } - View getView() { + @VisibleForTesting + /** + * @return a view which is attached to the view tree. + */ + public View getView() { return mView; } - Context getContext() { - return mContext; - } - /** * @return true if the monitoring should be deferred to the next frame, false otherwise. */ public boolean shouldDeferMonitor() { return mDeferMonitor; } + + @VisibleForTesting + public Handler getHandler() { + return mHandler; + } } /** @@ -1078,7 +1147,8 @@ public class InteractionJankMonitor { mReason = reason; } - public @Reasons int getReason() { + @Reasons + public int getReason() { return mReason; } } diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index b15d564fee71..a4d6bb4320f1 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -421,7 +421,7 @@ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"መተግበሪያው በእርስዎ ስልክ ላይ ስለተከማቹ እውቂያዎችዎ ያለ ውሂብን እንዲቀይር ያስችለዋል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብን እንዲሰርዙ ያስችላቸዋል።"</string> <string name="permlab_readCallLog" msgid="1739990210293505948">"የጥሪ ምዝግብ ማስታወሻን ያንብቡ"</string> <string name="permdesc_readCallLog" msgid="8964770895425873433">"ይህ መተግበሪያ የእርስዎን የጥሪ ታሪክ ማንበብ ይችላል።"</string> - <string name="permlab_writeCallLog" msgid="670292975137658895">"የጥሪ ምዝግብ ማስታወሻን ፃፍ"</string> + <string name="permlab_writeCallLog" msgid="670292975137658895">"የጥሪ ምዝግብ ማስታወሻን ጻፍ"</string> <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊተኮህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string> <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"መተግበሪያው ስለገቢ እና ወጪ ጥሪዎች ያለ ውሂብም ጨምሮ የእርስዎ Android TV መሣሪያ ምዝግብ ማስታወሻ እንዲቀይር ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች ይህን ተጠቅመው የስልክዎን ምዝግብ ማስታወሻ ሊደመስሱ ወይም ሊቀይሩ ይችላሉ።"</string> <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 9344e52841d3..4a6f8377f5ee 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1630,7 +1630,7 @@ <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Integrierter Bildschirm"</string> <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI-Bildschirm"</string> <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Overlay-Nr. <xliff:g id="ID">%1$d</xliff:g>"</string> - <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> + <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> × <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", sicher"</string> <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Muster vergessen"</string> <string name="kg_wrong_pattern" msgid="1342812634464179931">"Falsches Muster"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 409d69561356..f6b4ff4326c3 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -628,7 +628,7 @@ <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Appuyez pour supprimer votre empreinte faciale, puis ajoutez de nouveau votre visage"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurer le déverrouillage par reconnaissance faciale"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string> - <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pour utiliser Face Unlock, activez "<b>"Accès à l\'appareil photo"</b>" dans Paramètres > Confidentialité"</string> + <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pour utiliser le déverrouillage par reconnaissance faciale, activez "<b>"Accès à l\'appareil photo"</b>" dans Paramètres > Confidentialité"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Appuyez pour ajouter une empreinte digitale"</string> <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Déverrouillage par empreinte digitale"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 8066104d051d..37536fb9dacd 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -307,9 +307,9 @@ <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string> <string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइलें"</string> <string name="permgroupdesc_storage" msgid="5378659041354582769">"अपने डिवाइस में मौजूद फ़ाइलों का ऐक्सेस दें"</string> - <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string> + <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो के ऐक्सेस"</string> <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"आपके डिवाइस पर संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string> - <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string> + <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो के ऐक्सेस"</string> <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"आपके डिवाइस पर फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string> <string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफ़ोन"</string> <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडियो रिकॉर्ड करें"</string> @@ -555,7 +555,7 @@ <string name="permlab_disableKeyguard" msgid="3605253559020928505">"अपना स्क्रीन लॉक अक्षम करें"</string> <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"ऐप्स को कीलॉक और कोई भी संबद्ध पासवर्ड सुरक्षा बंद करने देता है. उदाहरण के लिए, इनकमिंग फ़ोन कॉल पाते समय फ़ोन, कीलॉक को बंद कर देता है, फिर कॉल खत्म होने पर कीलॉक को फिर से चालू कर देता है."</string> <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"जानें कि स्क्रीन लॉक कितना मुश्किल बनाया गया है"</string> - <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिल्कुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string> + <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिलकुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string> <string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाएं दिखाएं"</string> <string name="permdesc_postNotification" msgid="5974977162462877075">"ऐप्लिकेशन को सूचनाएं दिखाने की अनुमति दें"</string> <string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमीट्रिक हार्डवेयर इस्तेमाल करने दें"</string> @@ -649,9 +649,9 @@ <string name="face_acquired_recalibrate" msgid="8724013080976469746">"कृपया फिर से अपने चेहरे की पहचान कराएं."</string> <string name="face_acquired_too_different" msgid="2520389515612972889">"चेहरे की पहचान नहीं हुई. फिर से कोशिश करें."</string> <string name="face_acquired_too_similar" msgid="8882920552674125694">"अपने सिर की पोज़िशन को थोड़ा बदलें"</string> - <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string> - <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string> - <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string> + <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string> + <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string> + <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"आपके चेहरे को छिपाने वाली सभी चीज़ों को हटाएं."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"अपनी स्क्रीन के सबसे ऊपरी हिस्से को साफ़ करें, जिसमें काले रंग वाला बार भी शामिल है"</string> <string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"आपका पूरा चेहरा दिखना चाहिए"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index b4c864daf532..7f767c012c28 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -750,7 +750,7 @@ <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Mengizinkan pemegang memulai layar untuk meninjau keputusan izin. Tidak pernah dibutuhkan untuk aplikasi normal."</string> <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"mulai lihat fitur aplikasi"</string> <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Memungkinkan pemegang mulai melihat info fitur untuk aplikasi."</string> - <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi pengambilan sampel yang tinggi"</string> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi sampling yang tinggi"</string> <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Mengizinkan aplikasi mengambil sampel data sensor pada frekuensi yang lebih besar dari 200 Hz"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"Setel aturan sandi"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 0431b50daaea..5241ddaceea6 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1921,11 +1921,11 @@ <string name="user_creation_adding" msgid="7305185499667958364">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="supervised_user_creation_label" msgid="6884904353827427515">"Aggiungi utente supervisionato"</string> <string name="language_selection_title" msgid="52674936078683285">"Aggiungi una lingua"</string> - <string name="country_selection_title" msgid="5221495687299014379">"Area geografica preferita"</string> + <string name="country_selection_title" msgid="5221495687299014379">"Regione preferita"</string> <string name="search_language_hint" msgid="7004225294308793583">"Digita nome lingua"</string> <string name="language_picker_section_suggested" msgid="6556199184638990447">"Suggerite"</string> <string name="language_picker_section_all" msgid="1985809075777564284">"Tutte le lingue"</string> - <string name="region_picker_section_all" msgid="756441309928774155">"Tutte le aree geografiche"</string> + <string name="region_picker_section_all" msgid="756441309928774155">"Tutte le regioni"</string> <string name="locale_search_menu" msgid="6258090710176422934">"Cerca"</string> <string name="app_suspended_title" msgid="888873445010322650">"App non disponibile"</string> <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> non è al momento disponibile. Viene gestita tramite <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 8fb5b31988ee..74af0a4c45a9 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1448,7 +1448,7 @@ <string name="permdesc_route_media_output" msgid="1759683269387729675">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string> <string name="permlab_readInstallSessions" msgid="7279049337895583621">"インストールセッションの読み取り"</string> <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"インストールセッションの読み取りをアプリに許可します。これにより、アプリはアクティブパッケージのインストールに関する詳細情報を参照できるようになります。"</string> - <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"インストールパッケージのリクエスト"</string> + <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"request install packages"</string> <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"パッケージのインストールをリクエストすることをアプリケーションに許可します。"</string> <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"パッケージの削除のリクエスト"</string> <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"パッケージの削除をリクエストすることをアプリに許可します。"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 74bda7804c3e..15fc866023be 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -48,7 +48,7 @@ <string name="invalidPin" msgid="7542498253319440408">"4 ते 8 अंकांचा पिन टाइप करा."</string> <string name="invalidPuk" msgid="8831151490931907083">"8 अंकांचा किंवा मोठा PUK टाइप करा."</string> <string name="needPuk" msgid="7321876090152422918">"तुमचे सिम कार्ड PUK-लॉक केलेले आहे. ते अनलॉक करण्यासाठी PUK कोड टाइप करा."</string> - <string name="needPuk2" msgid="7032612093451537186">"सिम कार्ड अनावरोधित करण्यासाठी PUK2 टाइप करा."</string> + <string name="needPuk2" msgid="7032612093451537186">"सिम कार्ड अनब्लॉक करण्यासाठी PUK2 टाइप करा."</string> <string name="enablePin" msgid="2543771964137091212">"अयशस्वी, सिम/RUIM लॉक सुरू करा."</string> <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584"> <item quantity="other">सिम लॉक होण्यापूर्वी आपल्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न उर्वरित आहेत.</item> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index d8c7f9e3d462..4b59bd84802a 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1156,9 +1156,9 @@ <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string> <string name="app_running_notification_text" msgid="5120815883400228566">"ଅଧିକ ସୂଚନା ପାଇଁ କିମ୍ବା ଆପ୍ ବନ୍ଦ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="ok" msgid="2646370155170753815">"ଠିକ୍ ଅଛି"</string> - <string name="cancel" msgid="6908697720451760115">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="cancel" msgid="6908697720451760115">"ବାତିଲ କରନ୍ତୁ"</string> <string name="yes" msgid="9069828999585032361">"ଠିକ୍ ଅଛି"</string> - <string name="no" msgid="5122037903299899715">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="no" msgid="5122037903299899715">"ବାତିଲ କରନ୍ତୁ"</string> <string name="dialog_alert_title" msgid="651856561974090712">"ଧ୍ୟାନଦିଅନ୍ତୁ"</string> <string name="loading" msgid="3138021523725055037">"ଲୋଡ୍ କରାଯାଉଛି…"</string> <string name="capital_on" msgid="2770685323900821829">"ଚାଲୁ"</string> @@ -1179,9 +1179,9 @@ <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"<xliff:g id="APPLICATION">%1$s</xliff:g> ମାଧ୍ୟମରେ ଲିଙ୍କ୍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string> <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"<xliff:g id="APPLICATION">%2$s</xliff:g> ମାଧ୍ୟମରେ <xliff:g id="HOST">%1$s</xliff:g> ଲିଙ୍କ୍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string> <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"ଆକ୍ସେସ୍ ଦିଅନ୍ତୁ"</string> - <string name="whichEditApplication" msgid="6191568491456092812">"ସହିତ ଏଡିଟ୍ କରନ୍ତୁ"</string> - <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$sରେ ସଂଶୋଧନ କରନ୍ତୁ"</string> - <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ଏଡିଟ୍ କରନ୍ତୁ"</string> + <string name="whichEditApplication" msgid="6191568491456092812">"ସହିତ ଏଡିଟ କରନ୍ତୁ"</string> + <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$sରେ ଏଡିଟ କରନ୍ତୁ"</string> + <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ଏଡିଟ କରନ୍ତୁ"</string> <string name="whichSendApplication" msgid="4143847974460792029">"ସେୟାର୍ କରନ୍ତୁ"</string> <string name="whichSendApplicationNamed" msgid="4470386782693183461">"%1$s ସହିତ ସେୟାର୍ କରନ୍ତୁ"</string> <string name="whichSendApplicationLabel" msgid="7467813004769188515">"ସେୟାର୍ କରନ୍ତୁ"</string> @@ -1323,7 +1323,7 @@ <string name="sms_short_code_details" msgid="2723725738333388351">"ଏହା ଦ୍ୱାରା "<b>" ଆପଣଙ୍କ ମୋବାଇଲ୍ ଆକାଉଣ୍ଟରୁ ପଇସା କଟିପାରେ। "</b></string> <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>" ଆପଣଙ୍କ ମୋବାଇଲ୍ ଆକାଉଣ୍ଟରୁ ପଇସା କଟିପାରେ। "</b></string> <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"ପଠାନ୍ତୁ"</string> - <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"ବାତିଲ କରନ୍ତୁ"</string> <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"ମୋ ପସନ୍ଦ ମନେରଖନ୍ତୁ"</string> <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"ଏହାକୁ ଆପଣ ସେଟିଙ୍ଗ ଓ ଆପ୍ରେ ପରବର୍ତ୍ତୀ ସମୟରେ ବଦଳାଇପାରିବେ"</string> <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ସର୍ବଦା ଅନୁମତି ଦିଅନ୍ତୁ"</string> @@ -1360,7 +1360,7 @@ <string name="usb_power_notification_message" msgid="7284765627437897702">"ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି। ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ଆନାଲଗ୍ ଅଡିଓ ଆକ୍ସେସରୀ ଚିହ୍ନଟ ହେଲା"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ଏହି ଫୋନ୍ରେ କନେକ୍ଟ ଥିବା ଡିଭାଇସ୍ କମ୍ପାଟିବଲ୍ ନୁହେଁ। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> - <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ ସଂଯୁକ୍ତ ହୋଇଛି"</string> + <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ କନେକ୍ଟ କରାଯାଇଛି"</string> <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ଡିବଗିଂକୁ ବନ୍ଦ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ସଂଯୋଗ କରାଯାଇଛି"</string> @@ -1546,7 +1546,7 @@ <string name="date_picker_prev_month_button" msgid="3418694374017868369">"ପୂର୍ବ ମାସ"</string> <string name="date_picker_next_month_button" msgid="4858207337779144840">"ପରବର୍ତ୍ତୀ ମାସ"</string> <string name="keyboardview_keycode_alt" msgid="8997420058584292385">"ALT"</string> - <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ କରନ୍ତୁ"</string> <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ୍ କରନ୍ତୁ"</string> <string name="keyboardview_keycode_done" msgid="2524518019001653851">"ହୋଇଗଲା"</string> <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"ମୋଡ୍ ପରିବର୍ତ୍ତନ"</string> @@ -1569,7 +1569,7 @@ <string name="storage_usb_drive" msgid="448030813201444573">"USB ଡ୍ରାଇଭ୍"</string> <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ଡ୍ରାଇଭ୍"</string> <string name="storage_usb" msgid="2391213347883616886">"USB ଷ୍ଟୋରେଜ୍"</string> - <string name="extract_edit_menu_button" msgid="63954536535863040">"ଏଡିଟ୍ କରନ୍ତୁ"</string> + <string name="extract_edit_menu_button" msgid="63954536535863040">"ଏଡିଟ କରନ୍ତୁ"</string> <string name="data_usage_warning_title" msgid="9034893717078325845">"ଡାଟା ଚେତାବନୀ"</string> <string name="data_usage_warning_body" msgid="1669325367188029454">"ଆପଣ <xliff:g id="APP">%s</xliff:g> ଡାଟା ବ୍ୟବହାର କରିସାରିଛନ୍ତି"</string> <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"ମୋବାଇଲ୍ ଡାଟା ଧାର୍ଯ୍ୟ ସୀମାରେ ପହଞ୍ଚିଲା"</string> @@ -1695,7 +1695,7 @@ <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"ଭଲ୍ୟୁମ୍ କୀ ସର୍ଟକଟ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string> <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ବନ୍ଦ ହୋଇଯାଇଛି"</string> - <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ"</string> + <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ହୋଇଗଲା"</string> <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ଶର୍ଟକଟ୍ ବନ୍ଦ କରନ୍ତୁ"</string> <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string> @@ -2048,7 +2048,7 @@ <string name="log_access_confirmation_body" msgid="6581985716241928135">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ବି ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି। ଅଧିକ ଜାଣନ୍ତୁ"</string> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍କୁ ଦେଖାଇବା ପାଇଁ ଚାହେଁ"</string> - <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ୍ କରନ୍ତୁ"</string> + <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ କରନ୍ତୁ"</string> <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଭାଇବ୍ରେଟ୍ ହେବ"</string> <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ନିଃଶବ୍ଦ କରିଦିଆଯିବ"</string> <string name="notification_channel_system_changes" msgid="2462010596920209678">"ସିଷ୍ଟମ୍ରେ ପରିବର୍ତ୍ତନ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index cc3af05e200a..3635e69c2cac 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1272,7 +1272,7 @@ <string name="volume_ringtone" msgid="134784084629229029">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string> <string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string> <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth ਰਾਹੀਂ ਪਲੇ ਕਰ ਰਿਹਾ ਹੈ"</string> - <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਖਾਮੋਸ਼ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string> + <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਸ਼ਾਂਤ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string> <string name="volume_call" msgid="7625321655265747433">"ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string> <string name="volume_bluetooth_call" msgid="2930204618610115061">"ਬਲੂਟੁੱਥ ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string> <string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਦੀ ਅਵਾਜ਼"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index ce8837b14011..0d2f038a49d7 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -2065,7 +2065,7 @@ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Zavrieť"</string> <string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string> <string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavenia"</string> - <string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparát"</string> + <string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string> <string name="notification_appops_microphone_active" msgid="581333393214739332">"Mikrofón"</string> <string name="notification_appops_overlay_active" msgid="5571732753262836481">"sa zobrazuje cez ďalšie aplikácie na obrazovke"</string> <string name="notification_feedback_indicator" msgid="663476517711323016">"Poskytnúť spätnú väzbu"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 40a8c6129038..77a6cdcf060f 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -2270,7 +2270,7 @@ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Återaktivera enhetens mikrofon"</string> <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Återaktivera enhetens kamera"</string> <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"För <b><xliff:g id="APP">%s</xliff:g></b> och alla appar och tjänster"</string> - <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Återaktivera"</string> + <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Avblockera"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorintegritet"</string> <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appikon"</string> <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Appens varumärkesbild"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 64789fb32dcb..721f76bc187c 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1689,7 +1689,7 @@ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్పై ఉండే కంటెంట్ మొత్తాన్ని చదవగలుగుతుంది మరియు ఇతర యాప్లలో కూడా ఈ కంటెంట్ను ప్రదర్శిస్తుంది."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయగలగడం"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్తో చేసే ఇంటరాక్షన్లను లేదా హార్డ్వేర్ సెన్సార్ను ట్రాక్ చేస్తూ మీ తరఫున యాప్లతో ఇంటరాక్ట్ చేయగలదు."</string> - <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించు"</string> + <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించండి"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"నిరాకరించు"</string> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ఫీచర్ని ఉపయోగించడం ప్రారంభించడానికి, దాన్ని ట్యాప్ చేయండి:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"యాక్సెసిబిలిటీ బటన్తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string> @@ -1975,7 +1975,7 @@ <string name="tooltip_popup_title" msgid="7863719020269945722">"సాధనం చిట్కా"</string> <string name="app_category_game" msgid="4534216074910244790">"గేమ్లు"</string> <string name="app_category_audio" msgid="8296029904794676222">"సంగీతం & ఆడియో"</string> - <string name="app_category_video" msgid="2590183854839565814">"చలనచిత్రాలు & వీడియో"</string> + <string name="app_category_video" msgid="2590183854839565814">"సినిమాలు & వీడియో"</string> <string name="app_category_image" msgid="7307840291864213007">"ఫోటోలు, ఇమేజ్లు"</string> <string name="app_category_social" msgid="2278269325488344054">"సామాజికం & కమ్యూనికేషన్"</string> <string name="app_category_news" msgid="1172762719574964544">"వార్తలు & వార్తాపత్రికలు"</string> diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java index 09fc7ea6fffd..e068730e9bda 100644 --- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java @@ -36,6 +36,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.only; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -83,6 +84,7 @@ public class FrameTrackerTest { private StatsLogWrapper mStatsLog; private ArgumentCaptor<OnJankDataListener> mListenerCapture; private SurfaceControl mSurfaceControl; + private ArgumentCaptor<Runnable> mRunnableArgumentCaptor; @Before public void setup() { @@ -99,6 +101,8 @@ public class FrameTrackerTest { mSurfaceControl = new SurfaceControl.Builder().setName("Surface").build(); mViewRootWrapper = mock(ViewRootWrapper.class); when(mViewRootWrapper.getSurfaceControl()).thenReturn(mSurfaceControl); + doNothing().when(mViewRootWrapper).addSurfaceChangedCallback(any()); + doNothing().when(mViewRootWrapper).removeSurfaceChangedCallback(any()); mSurfaceControlWrapper = mock(SurfaceControlWrapper.class); mListenerCapture = ArgumentCaptor.forClass(OnJankDataListener.class); @@ -109,23 +113,29 @@ public class FrameTrackerTest { mChoreographer = mock(ChoreographerWrapper.class); mStatsLog = mock(StatsLogWrapper.class); + mRunnableArgumentCaptor = ArgumentCaptor.forClass(Runnable.class); } private FrameTracker spyFrameTracker(int cuj, String postfix, boolean surfaceOnly) { + InteractionJankMonitor monitor = mock(InteractionJankMonitor.class); Handler handler = mRule.getActivity().getMainThreadHandler(); Session session = new Session(cuj, postfix); Configuration config = mock(Configuration.class); when(config.isSurfaceOnly()).thenReturn(surfaceOnly); when(config.getSurfaceControl()).thenReturn(mSurfaceControl); when(config.shouldDeferMonitor()).thenReturn(true); + View view = mRule.getActivity().getWindow().getDecorView(); + Handler spyHandler = spy(new Handler(handler.getLooper())); + when(config.getView()).thenReturn(surfaceOnly ? null : view); + when(config.getHandler()).thenReturn(spyHandler); FrameTracker frameTracker = Mockito.spy( - new FrameTracker(session, handler, mRenderer, mViewRootWrapper, + new FrameTracker(monitor, session, spyHandler, mRenderer, mViewRootWrapper, mSurfaceControlWrapper, mChoreographer, mWrapper, mStatsLog, /* traceThresholdMissedFrames= */ 1, /* traceThresholdFrameTimeMillis= */ -1, /* FrameTrackerListener= */ null, config)); doNothing().when(frameTracker).triggerPerfetto(); - doNothing().when(frameTracker).postTraceStartMarker(); + doNothing().when(frameTracker).postTraceStartMarker(mRunnableArgumentCaptor.capture()); return frameTracker; } @@ -140,6 +150,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // send first frame with a long duration - should not be taken into account @@ -173,6 +184,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // send first frame - not janky @@ -208,6 +220,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // send first frame - janky @@ -243,6 +256,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // send first frame - not janky @@ -278,6 +292,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // send first frame - not janky @@ -319,6 +334,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // send first frame - not janky @@ -332,7 +348,7 @@ public class FrameTrackerTest { tracker.end(FrameTracker.REASON_END_NORMAL); // Send incomplete callback for 102L - sendSfFrame(102L, JANK_NONE); + sendSfFrame(tracker, 102L, JANK_NONE); // Send janky but complete callbck fo 103L sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L); @@ -356,6 +372,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer).addObserver(any()); // First frame - not janky @@ -380,6 +397,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // end the trace session @@ -403,6 +421,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mRenderer, only()).addObserver(any()); // end the trace session at the same vsync id, end vsync id will less than the begin one. @@ -444,6 +463,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mSurfaceControlWrapper).addJankStatsListener(any(), any()); // First frame - not janky @@ -479,6 +499,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mSurfaceControlWrapper).addJankStatsListener(any(), any()); // First frame - janky @@ -514,6 +535,7 @@ public class FrameTrackerTest { when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mSurfaceControlWrapper).addJankStatsListener(any(), any()); // First frame - not janky @@ -548,6 +570,7 @@ public class FrameTrackerTest { CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true); when(mChoreographer.getVsyncId()).thenReturn(100L); tracker.begin(); + mRunnableArgumentCaptor.getValue().run(); verify(mSurfaceControlWrapper).addJankStatsListener(any(), any()); sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 100L); sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L); @@ -594,7 +617,7 @@ public class FrameTrackerTest { if (!tracker.mSurfaceOnly) { sendHwuiFrame(tracker, durationMillis, vsyncId, firstWindowFrame); } - sendSfFrame(vsyncId, jankType); + sendSfFrame(tracker, vsyncId, jankType); } private void sendHwuiFrame(FrameTracker tracker, long durationMillis, long vsyncId, @@ -604,12 +627,18 @@ public class FrameTrackerTest { .getMetric(FrameMetrics.FIRST_DRAW_FRAME); doReturn(TimeUnit.MILLISECONDS.toNanos(durationMillis)) .when(mWrapper).getMetric(FrameMetrics.TOTAL_DURATION); + final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); + doNothing().when(tracker).postCallback(captor.capture()); tracker.onFrameMetricsAvailable(0); + captor.getValue().run(); } - private void sendSfFrame(long vsyncId, @JankType int jankType) { + private void sendSfFrame(FrameTracker tracker, long vsyncId, @JankType int jankType) { + final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); + doNothing().when(tracker).postCallback(captor.capture()); mListenerCapture.getValue().onJankDataAvailable(new JankData[] { new JankData(vsyncId, jankType) }); + captor.getValue().run(); } } diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java index 5a6fd5317bbc..d96f041c13f8 100644 --- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java +++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java @@ -93,7 +93,7 @@ public class InteractionJankMonitorTest { @Test public void testBeginEnd() { InteractionJankMonitor monitor = createMockedInteractionJankMonitor(); - FrameTracker tracker = createMockedFrameTracker(null); + FrameTracker tracker = createMockedFrameTracker(monitor, null); doReturn(tracker).when(monitor).createFrameTracker(any(), any()); doNothing().when(tracker).begin(); doReturn(true).when(tracker).end(anyInt()); @@ -134,7 +134,7 @@ public class InteractionJankMonitorTest { public void testBeginTimeout() { ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); InteractionJankMonitor monitor = createMockedInteractionJankMonitor(); - FrameTracker tracker = createMockedFrameTracker(null); + FrameTracker tracker = createMockedFrameTracker(monitor, null); doReturn(tracker).when(monitor).createFrameTracker(any(), any()); doNothing().when(tracker).begin(); doReturn(true).when(tracker).cancel(anyInt()); @@ -180,7 +180,8 @@ public class InteractionJankMonitorTest { return monitor; } - private FrameTracker createMockedFrameTracker(FrameTracker.FrameTrackerListener listener) { + private FrameTracker createMockedFrameTracker(InteractionJankMonitor monitor, + FrameTracker.FrameTrackerListener listener) { Session session = spy(new Session(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX)); doReturn(false).when(session).logToStatsd(); @@ -190,6 +191,7 @@ public class InteractionJankMonitorTest { ViewRootWrapper viewRoot = spy(new ViewRootWrapper(mView.getViewRootImpl())); doNothing().when(viewRoot).addSurfaceChangedCallback(any()); + doNothing().when(viewRoot).removeSurfaceChangedCallback(any()); SurfaceControlWrapper surfaceControl = mock(SurfaceControlWrapper.class); doNothing().when(surfaceControl).addJankStatsListener(any(), any()); @@ -200,15 +202,18 @@ public class InteractionJankMonitorTest { Configuration configuration = mock(Configuration.class); when(configuration.isSurfaceOnly()).thenReturn(false); + when(configuration.getView()).thenReturn(mView); + when(configuration.getHandler()).thenReturn(mView.getHandler()); - FrameTracker tracker = spy(new FrameTracker(session, mWorker.getThreadHandler(), + FrameTracker tracker = spy(new FrameTracker(monitor, session, mWorker.getThreadHandler(), threadedRenderer, viewRoot, surfaceControl, choreographer, new FrameMetricsWrapper(), new StatsLogWrapper(), /* traceThresholdMissedFrames= */ 1, /* traceThresholdFrameTimeMillis= */ -1, listener, configuration)); - doNothing().when(tracker).postTraceStartMarker(); + doNothing().when(tracker).postTraceStartMarker(any()); doNothing().when(tracker).triggerPerfetto(); + doReturn(configuration.getHandler()).when(tracker).getHandler(); return tracker; } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index 18086f552ea3..6bfb16a3c22d 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -25,8 +25,7 @@ import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect; import android.annotation.Nullable; import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityManager.AppTask; +import android.app.ActivityClient; import android.app.Application; import android.app.WindowConfiguration; import android.content.Context; @@ -34,7 +33,6 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.util.ArrayMap; -import android.util.Log; import androidx.annotation.NonNull; import androidx.window.common.CommonFoldingFeature; @@ -179,57 +177,49 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { private List<DisplayFeature> getDisplayFeatures( @NonNull Activity activity, List<CommonFoldingFeature> storedFeatures) { List<DisplayFeature> features = new ArrayList<>(); - int displayId = activity.getDisplay().getDisplayId(); - if (displayId != DEFAULT_DISPLAY) { - Log.w(TAG, "This sample doesn't support display features on secondary displays"); + if (!shouldReportDisplayFeatures(activity)) { return features; - } else if (isTaskInMultiWindowMode(activity)) { - // It is recommended not to report any display features in multi-window mode, since it - // won't be possible to synchronize the display feature positions with window movement. - return features; - } else { - for (CommonFoldingFeature baseFeature : storedFeatures) { - Integer state = convertToExtensionState(baseFeature.getState()); - if (state == null) { - continue; - } - Rect featureRect = baseFeature.getRect(); - rotateRectToDisplayRotation(displayId, featureRect); - transformToWindowSpaceRect(activity, featureRect); + } - if (!isRectZero(featureRect)) { - // TODO(b/228641877) Remove guarding if when fixed. - features.add(new FoldingFeature(featureRect, baseFeature.getType(), state)); - } + int displayId = activity.getDisplay().getDisplayId(); + for (CommonFoldingFeature baseFeature : storedFeatures) { + Integer state = convertToExtensionState(baseFeature.getState()); + if (state == null) { + continue; + } + Rect featureRect = baseFeature.getRect(); + rotateRectToDisplayRotation(displayId, featureRect); + transformToWindowSpaceRect(activity, featureRect); + + if (!isRectZero(featureRect)) { + // TODO(b/228641877): Remove guarding when fixed. + features.add(new FoldingFeature(featureRect, baseFeature.getType(), state)); } - return features; } + return features; } /** - * Checks whether the task associated with the activity is in multi-window. If task info is not - * available it defaults to {@code true}. + * Checks whether display features should be reported for the activity. + * TODO(b/238948678): Support reporting display features in all windowing modes. */ - private boolean isTaskInMultiWindowMode(@NonNull Activity activity) { - final ActivityManager am = activity.getSystemService(ActivityManager.class); - if (am == null) { - return true; - } - - final List<AppTask> appTasks = am.getAppTasks(); - final int taskId = activity.getTaskId(); - AppTask task = null; - for (AppTask t : appTasks) { - if (t.getTaskInfo().taskId == taskId) { - task = t; - break; - } + private boolean shouldReportDisplayFeatures(@NonNull Activity activity) { + int displayId = activity.getDisplay().getDisplayId(); + if (displayId != DEFAULT_DISPLAY) { + // Display features are not supported on secondary displays. + return false; } - if (task == null) { - // The task might be removed on the server already. - return true; + final int taskWindowingMode = ActivityClient.getInstance().getTaskWindowingMode( + activity.getActivityToken()); + if (taskWindowingMode == -1) { + // If we cannot determine the task windowing mode for any reason, it is likely that we + // won't be able to determine its position correctly as well. DisplayFeatures' bounds + // in this case can't be computed correctly, so we should skip. + return false; } - return WindowConfiguration.inMultiWindowMode(task.getTaskInfo().getWindowingMode()); + // It is recommended not to report any display features in multi-window mode, since it + // won't be possible to synchronize the display feature positions with window movement. + return !WindowConfiguration.inMultiWindowMode(taskWindowingMode); } /** diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 0f2d38bfeb65..87ac5d64ff85 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -72,8 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string> - <!-- no translation found for restart_button_description (6712141648865547958) --> - <skip /> + <string name="restart_button_description" msgid="6712141648865547958">"टैप करके ऐप्लिकेशन को रीस्टार्ट करें और बेहतर व्यू पाएं."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index b4bc3909c08f..8fb7adebe930 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -72,7 +72,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string> - <string name="restart_button_description" msgid="6712141648865547958">"請輕觸並重新啟動此應用程式,取得更良好的觀看體驗。"</string> + <string name="restart_button_description" msgid="6712141648865547958">"輕按並重新啟動此應用程式,以取得更佳的觀看體驗。"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題?\n輕按即可修正"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java index 992f31562145..6694e441084b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java @@ -17,7 +17,16 @@ package com.android.wm.shell; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT; +import android.os.Build; +import android.os.SystemClock; +import android.util.Pair; + +import androidx.annotation.VisibleForTesting; + +import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.activityembedding.ActivityEmbeddingController; import com.android.wm.shell.bubbles.BubbleController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; @@ -37,10 +46,12 @@ import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.unfold.UnfoldAnimationController; import com.android.wm.shell.unfold.UnfoldTransitionHandler; +import java.util.ArrayList; import java.util.Optional; /** - * The entry point implementation into the shell for initializing shell internal state. + * The entry point implementation into the shell for initializing shell internal state. Classes + * which need to setup on start should inject an instance of this class and add an init callback. */ public class ShellInitImpl { private static final String TAG = ShellInitImpl.class.getSimpleName(); @@ -62,8 +73,12 @@ public class ShellInitImpl { private final Transitions mTransitions; private final StartingWindowController mStartingWindow; private final Optional<RecentTasksController> mRecentTasks; + private final Optional<ActivityEmbeddingController> mActivityEmbeddingOptional; private final InitImpl mImpl = new InitImpl(); + // An ordered list of init callbacks to be made once shell is first started + private final ArrayList<Pair<String, Runnable>> mInitCallbacks = new ArrayList<>(); + private boolean mHasInitialized; public ShellInitImpl( DisplayController displayController, @@ -80,6 +95,7 @@ public class ShellInitImpl { Optional<UnfoldTransitionHandler> unfoldTransitionHandler, Optional<FreeformTaskListener<?>> freeformTaskListenerOptional, Optional<RecentTasksController> recentTasks, + Optional<ActivityEmbeddingController> activityEmbeddingOptional, Transitions transitions, StartingWindowController startingWindow, ShellExecutor mainExecutor) { @@ -97,6 +113,7 @@ public class ShellInitImpl { mUnfoldTransitionHandler = unfoldTransitionHandler; mFreeformTaskListenerOptional = freeformTaskListenerOptional; mRecentTasks = recentTasks; + mActivityEmbeddingOptional = activityEmbeddingOptional; mTransitions = transitions; mMainExecutor = mainExecutor; mStartingWindow = startingWindow; @@ -106,7 +123,7 @@ public class ShellInitImpl { return mImpl; } - private void init() { + private void legacyInit() { // Start listening for display and insets changes mDisplayController.initialize(); mDisplayInsetsController.initialize(); @@ -126,6 +143,7 @@ public class ShellInitImpl { if (Transitions.ENABLE_SHELL_TRANSITIONS) { mTransitions.register(mShellTaskOrganizer); + mActivityEmbeddingOptional.ifPresent(ActivityEmbeddingController::init); mUnfoldTransitionHandler.ifPresent(UnfoldTransitionHandler::init); if (mSplitScreenOptional.isPresent() && mPipTouchHandlerOptional.isPresent()) { final DefaultMixedHandler mixedHandler = new DefaultMixedHandler(mTransitions, @@ -153,12 +171,52 @@ public class ShellInitImpl { mKidsModeTaskOrganizer.initialize(mStartingWindow); } + /** + * Adds a callback to the ordered list of callbacks be made when Shell is first started. This + * can be used in class constructors when dagger is used to ensure that the initialization order + * matches the dependency order. + */ + public <T extends Object> void addInitCallback(Runnable r, T instance) { + if (mHasInitialized) { + if (Build.isDebuggable()) { + // All callbacks must be added prior to the Shell being initialized + throw new IllegalArgumentException("Can not add callback after init"); + } + return; + } + final String className = instance.getClass().getSimpleName(); + mInitCallbacks.add(new Pair<>(className, r)); + ProtoLog.v(WM_SHELL_INIT, "Adding init callback for %s", className); + } + + /** + * Calls all the init callbacks when the Shell is first starting. + */ + @VisibleForTesting + public void init() { + ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size()); + // Init in order of registration + for (int i = 0; i < mInitCallbacks.size(); i++) { + final Pair<String, Runnable> info = mInitCallbacks.get(i); + final long t1 = SystemClock.uptimeMillis(); + info.second.run(); + final long t2 = SystemClock.uptimeMillis(); + ProtoLog.v(WM_SHELL_INIT, "\t%s took %dms", info.first, (t2 - t1)); + } + mInitCallbacks.clear(); + + // TODO: To be removed + legacyInit(); + + mHasInitialized = true; + } + @ExternalThread private class InitImpl implements ShellInit { @Override public void init() { try { - mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init()); + mMainExecutor.executeBlocking(ShellInitImpl.this::init); } catch (InterruptedException e) { throw new RuntimeException("Failed to initialize the Shell in 2s", e); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index e0ad9cb66780..7d7c59eb17da 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -500,7 +500,9 @@ public class ShellTaskOrganizer extends TaskOrganizer implements || (taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME && taskInfo.isVisible); final boolean focusTaskChanged = (mLastFocusedTaskInfo == null - || mLastFocusedTaskInfo.taskId != taskInfo.taskId) && isFocusedOrHome; + || mLastFocusedTaskInfo.taskId != taskInfo.taskId + || mLastFocusedTaskInfo.getWindowingMode() != taskInfo.getWindowingMode()) + && isFocusedOrHome; if (focusTaskChanged) { for (int i = 0; i < mFocusListeners.size(); i++) { mFocusListeners.valueAt(i).onFocusTaskChanged(taskInfo); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java new file mode 100644 index 000000000000..82b0270698e4 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.activityembedding; + +import static android.window.TransitionInfo.FLAG_IS_EMBEDDED; + +import android.content.Context; +import android.os.IBinder; +import android.view.SurfaceControl; +import android.window.TransitionInfo; +import android.window.TransitionRequestInfo; +import android.window.WindowContainerTransaction; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.wm.shell.transition.Transitions; + +/** + * Responsible for handling ActivityEmbedding related transitions. + */ +public class ActivityEmbeddingController implements Transitions.TransitionHandler { + + private final Context mContext; + private final Transitions mTransitions; + + public ActivityEmbeddingController(Context context, Transitions transitions) { + mContext = context; + mTransitions = transitions; + } + + /** Registers to handle transitions. */ + public void init() { + mTransitions.addHandler(this); + } + + @Override + public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction startTransaction, + @NonNull SurfaceControl.Transaction finishTransaction, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + // TODO(b/207070762) Handle AE animation as a part of other transitions. + // Only handle the transition if all containers are embedded. + for (TransitionInfo.Change change : info.getChanges()) { + if (!isEmbedded(change)) { + return false; + } + } + + // TODO(b/207070762) Implement AE animation. + startTransaction.apply(); + finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); + return true; + } + + @Nullable + @Override + public WindowContainerTransaction handleRequest(@NonNull IBinder transition, + @NonNull TransitionRequestInfo request) { + return null; + } + + private static boolean isEmbedded(@NonNull TransitionInfo.Change change) { + return (change.getFlags() & FLAG_IS_EMBEDDED) != 0; + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index a2c40550b583..d7f1292cb717 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -85,7 +85,6 @@ import androidx.annotation.MainThread; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.TaskViewTransitions; @@ -102,6 +101,8 @@ import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.pip.PinnedStackListenerForwarder; +import com.android.wm.shell.sysui.ConfigurationChangeListener; +import com.android.wm.shell.sysui.ShellController; import java.io.PrintWriter; import java.util.ArrayList; @@ -120,7 +121,7 @@ import java.util.function.IntConsumer; * * The controller manages addition, removal, and visible state of bubbles on screen. */ -public class BubbleController { +public class BubbleController implements ConfigurationChangeListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES; @@ -156,6 +157,7 @@ public class BubbleController { private final DisplayController mDisplayController; private final TaskViewTransitions mTaskViewTransitions; private final SyncTransactionQueue mSyncQueue; + private final ShellController mShellController; // Used to post to main UI thread private final ShellExecutor mMainExecutor; @@ -223,44 +225,9 @@ public class BubbleController { /** Drag and drop controller to register listener for onDragStarted. */ private DragAndDropController mDragAndDropController; - /** - * Creates an instance of the BubbleController. - */ - public static BubbleController create(Context context, - @Nullable BubbleStackView.SurfaceSynchronizer synchronizer, - FloatingContentCoordinator floatingContentCoordinator, - @Nullable IStatusBarService statusBarService, - WindowManager windowManager, - WindowManagerShellWrapper windowManagerShellWrapper, - UserManager userManager, - LauncherApps launcherApps, - TaskStackListenerImpl taskStackListener, - UiEventLogger uiEventLogger, - ShellTaskOrganizer organizer, - DisplayController displayController, - Optional<OneHandedController> oneHandedOptional, - DragAndDropController dragAndDropController, - @ShellMainThread ShellExecutor mainExecutor, - @ShellMainThread Handler mainHandler, - @ShellBackgroundThread ShellExecutor bgExecutor, - TaskViewTransitions taskViewTransitions, - SyncTransactionQueue syncQueue) { - BubbleLogger logger = new BubbleLogger(uiEventLogger); - BubblePositioner positioner = new BubblePositioner(context, windowManager); - BubbleData data = new BubbleData(context, logger, positioner, mainExecutor); - return new BubbleController(context, data, synchronizer, floatingContentCoordinator, - new BubbleDataRepository(context, launcherApps, mainExecutor), - statusBarService, windowManager, windowManagerShellWrapper, userManager, - launcherApps, logger, taskStackListener, organizer, positioner, displayController, - oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor, - taskViewTransitions, syncQueue); - } - - /** - * Testing constructor. - */ - @VisibleForTesting - protected BubbleController(Context context, + + public BubbleController(Context context, + ShellController shellController, BubbleData data, @Nullable BubbleStackView.SurfaceSynchronizer synchronizer, FloatingContentCoordinator floatingContentCoordinator, @@ -283,6 +250,7 @@ public class BubbleController { TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue) { mContext = context; + mShellController = shellController; mLauncherApps = launcherApps; mBarService = statusBarService == null ? IStatusBarService.Stub.asInterface( @@ -451,6 +419,8 @@ public class BubbleController { // Clear out any persisted bubbles on disk that no longer have a valid user. List<UserInfo> users = mUserManager.getAliveUsers(); mDataRepository.sanitizeBubbles(users); + + mShellController.addConfigurationChangeListener(this); } @VisibleForTesting @@ -835,7 +805,8 @@ public class BubbleController { mSavedBubbleKeysPerUser.remove(userId); } - private void updateForThemeChanges() { + @Override + public void onThemeChanged() { if (mStackView != null) { mStackView.onThemeChanged(); } @@ -855,7 +826,8 @@ public class BubbleController { } } - private void onConfigChanged(Configuration newConfig) { + @Override + public void onConfigurationChanged(Configuration newConfig) { if (mBubblePositioner != null) { mBubblePositioner.update(); } @@ -1715,13 +1687,6 @@ public class BubbleController { } @Override - public void updateForThemeChanges() { - mMainExecutor.execute(() -> { - BubbleController.this.updateForThemeChanges(); - }); - } - - @Override public void expandStackAndSelectBubble(BubbleEntry entry) { mMainExecutor.execute(() -> { BubbleController.this.expandStackAndSelectBubble(entry); @@ -1860,13 +1825,6 @@ public class BubbleController { } @Override - public void onConfigChanged(Configuration newConfig) { - mMainExecutor.execute(() -> { - BubbleController.this.onConfigChanged(newConfig); - }); - } - - @Override public void onNotificationPanelExpandedChanged(boolean expanded) { mMainExecutor.execute( () -> BubbleController.this.onNotificationPanelExpandedChanged(expanded)); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java index 0072da19b9ef..f8ccf2364b4c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java @@ -107,9 +107,6 @@ public interface Bubbles { /** Tell the stack of bubbles to collapse. */ void collapseStack(); - /** Tell the controller need update its UI to fit theme. */ - void updateForThemeChanges(); - /** * Request the stack expand if needed, then select the specified Bubble as current. * If no bubble exists for this entry, one is created. @@ -255,13 +252,6 @@ public interface Bubbles { */ void onUserRemoved(int removedUserId); - /** - * Called when config changed. - * - * @param newConfig the new config. - */ - void onConfigChanged(Configuration newConfig); - /** Description of current bubble state. */ void dump(PrintWriter pw, String[] args); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index 6fb021ea5e2f..74f8bf9ac863 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -50,6 +50,8 @@ import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.R; import com.android.wm.shell.common.SurfaceUtils; +import java.util.function.Consumer; + /** * Handles split decor like showing resizing hint for a specific split. */ @@ -212,7 +214,7 @@ public class SplitDecorManager extends WindowlessWindowManager { newBounds.height() / 2 - mIconSize / 2); if (animate) { - startFadeAnimation(show, false /* isResized */); + startFadeAnimation(show, null /* finishedConsumer */); mShown = show; } } @@ -243,15 +245,29 @@ public class SplitDecorManager extends WindowlessWindowManager { mFadeAnimator.cancel(); } if (mShown) { - startFadeAnimation(false /* show */, true /* isResized */); - mShown = false; + fadeOutDecor(null /* finishedCallback */); } else { // Decor surface is hidden so release it directly. releaseDecor(t); } } - private void startFadeAnimation(boolean show, boolean isResized) { + /** Fade-out decor surface with animation end callback, if decor is hidden, run the callback + * directly. */ + public void fadeOutDecor(Runnable finishedCallback) { + if (mShown) { + startFadeAnimation(false /* show */, transaction -> { + releaseDecor(transaction); + if (finishedCallback != null) finishedCallback.run(); + }); + mShown = false; + } else { + if (finishedCallback != null) finishedCallback.run(); + } + } + + private void startFadeAnimation(boolean show, + Consumer<SurfaceControl.Transaction> finishedConsumer) { final SurfaceControl.Transaction animT = new SurfaceControl.Transaction(); mFadeAnimator = ValueAnimator.ofFloat(0f, 1f); mFadeAnimator.setDuration(FADE_DURATION); @@ -285,8 +301,8 @@ public class SplitDecorManager extends WindowlessWindowManager { animT.hide(mIconLeash); } } - if (isResized) { - releaseDecor(animT); + if (finishedConsumer != null) { + finishedConsumer.accept(animT); } animT.apply(); animT.close(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 2e64c945ca25..b69cbfa83d7c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -32,6 +32,7 @@ import static com.android.wm.shell.animation.Interpolators.SLOWDOWN_INTERPOLATOR import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -449,11 +450,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange switch (snapTarget.flag) { case FLAG_DISMISS_START: flingDividePosition(currentPosition, snapTarget.position, - () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */)); + () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */, + EXIT_REASON_DRAG_DIVIDER)); break; case FLAG_DISMISS_END: flingDividePosition(currentPosition, snapTarget.position, - () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */)); + () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */, + EXIT_REASON_DRAG_DIVIDER)); break; default: flingDividePosition(currentPosition, snapTarget.position, @@ -509,6 +512,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */); } + /** Fling divider from current position to end or start position then exit */ + public void flingDividerToDismiss(boolean toEnd, int reason) { + final int target = toEnd ? mDividerSnapAlgorithm.getDismissEndTarget().position + : mDividerSnapAlgorithm.getDismissStartTarget().position; + flingDividePosition(getDividePosition(), target, + () -> mSplitLayoutHandler.onSnappedToDismiss(toEnd, reason)); + } + @VisibleForTesting void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) { if (from == to) { @@ -758,7 +769,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange public interface SplitLayoutHandler { /** Calls when dismissing split. */ - void onSnappedToDismiss(boolean snappedToEnd); + void onSnappedToDismiss(boolean snappedToEnd, int reason); /** * Calls when resizing the split bounds. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java index 1ea5e21a2c1e..81904e291ad1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java @@ -48,6 +48,7 @@ import com.android.wm.shell.pip.tv.TvPipNotificationController; import com.android.wm.shell.pip.tv.TvPipTaskOrganizer; import com.android.wm.shell.pip.tv.TvPipTransition; import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.transition.Transitions; import java.util.Optional; @@ -64,6 +65,7 @@ public abstract class TvPipModule { @Provides static Optional<Pip> providePip( Context context, + ShellController shellController, TvPipBoundsState tvPipBoundsState, TvPipBoundsAlgorithm tvPipBoundsAlgorithm, TvPipBoundsController tvPipBoundsController, @@ -81,6 +83,7 @@ public abstract class TvPipModule { return Optional.of( TvPipController.create( context, + shellController, tvPipBoundsState, tvPipBoundsAlgorithm, tvPipBoundsController, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java index 2ea111b113d8..ed5e24776bfa 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java @@ -38,6 +38,7 @@ import com.android.wm.shell.TaskViewFactory; import com.android.wm.shell.TaskViewFactoryController; import com.android.wm.shell.TaskViewTransitions; import com.android.wm.shell.WindowManagerShellWrapper; +import com.android.wm.shell.activityembedding.ActivityEmbeddingController; import com.android.wm.shell.back.BackAnimation; import com.android.wm.shell.back.BackAnimationController; import com.android.wm.shell.bubbles.BubbleController; @@ -82,6 +83,8 @@ import com.android.wm.shell.startingsurface.StartingSurface; import com.android.wm.shell.startingsurface.StartingWindowController; import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm; import com.android.wm.shell.startingsurface.phone.PhoneStartingWindowTypeAlgorithm; +import com.android.wm.shell.sysui.ShellController; +import com.android.wm.shell.sysui.ShellInterface; import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelperController; import com.android.wm.shell.transition.ShellTransitions; @@ -159,10 +162,13 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static DragAndDropController provideDragAndDropController(Context context, - DisplayController displayController, UiEventLogger uiEventLogger, - IconProvider iconProvider, @ShellMainThread ShellExecutor mainExecutor) { - return new DragAndDropController(context, displayController, uiEventLogger, iconProvider, - mainExecutor); + ShellController shellController, + DisplayController displayController, + UiEventLogger uiEventLogger, + IconProvider iconProvider, + @ShellMainThread ShellExecutor mainExecutor) { + return new DragAndDropController(context, shellController, displayController, uiEventLogger, + iconProvider, mainExecutor); } @WMSingleton @@ -377,9 +383,11 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static Optional<HideDisplayCutoutController> provideHideDisplayCutoutController(Context context, - DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor) { + ShellController shellController, DisplayController displayController, + @ShellMainThread ShellExecutor mainExecutor) { return Optional.ofNullable( - HideDisplayCutoutController.create(context, displayController, mainExecutor)); + HideDisplayCutoutController.create(context, shellController, displayController, + mainExecutor)); } // @@ -621,6 +629,34 @@ public abstract class WMShellBaseModule { taskViewTransitions); } + + // + // ActivityEmbedding + // + + @WMSingleton + @Provides + static Optional<ActivityEmbeddingController> provideActivityEmbeddingController( + Context context, Transitions transitions) { + return Optional.of(new ActivityEmbeddingController(context, transitions)); + } + + // + // SysUI -> Shell interface + // + + @WMSingleton + @Provides + static ShellInterface provideShellSysuiCallbacks(ShellController shellController) { + return shellController.asShell(); + } + + @WMSingleton + @Provides + static ShellController provideShellController(@ShellMainThread ShellExecutor mainExecutor) { + return new ShellController(mainExecutor); + } + // // Misc // @@ -647,6 +683,7 @@ public abstract class WMShellBaseModule { Optional<UnfoldTransitionHandler> unfoldTransitionHandler, Optional<FreeformTaskListener<?>> freeformTaskListener, Optional<RecentTasksController> recentTasksOptional, + Optional<ActivityEmbeddingController> activityEmbeddingOptional, Transitions transitions, StartingWindowController startingWindow, @ShellMainThread ShellExecutor mainExecutor) { @@ -664,6 +701,7 @@ public abstract class WMShellBaseModule { unfoldTransitionHandler, freeformTaskListener, recentTasksOptional, + activityEmbeddingOptional, transitions, startingWindow, mainExecutor); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index a8c1071eb69e..fb51473a4d98 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -31,6 +31,10 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.TaskViewTransitions; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.bubbles.BubbleController; +import com.android.wm.shell.bubbles.BubbleData; +import com.android.wm.shell.bubbles.BubbleDataRepository; +import com.android.wm.shell.bubbles.BubbleLogger; +import com.android.wm.shell.bubbles.BubblePositioner; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; @@ -67,6 +71,7 @@ import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.unfold.ShellUnfoldProgressProvider; import com.android.wm.shell.unfold.UnfoldAnimationController; @@ -104,10 +109,34 @@ public abstract class WMShellModule { // Bubbles // + @WMSingleton + @Provides + static BubbleLogger provideBubbleLogger(UiEventLogger uiEventLogger) { + return new BubbleLogger(uiEventLogger); + } + + @WMSingleton + @Provides + static BubblePositioner provideBubblePositioner(Context context, + WindowManager windowManager) { + return new BubblePositioner(context, windowManager); + } + + @WMSingleton + @Provides + static BubbleData provideBubbleData(Context context, + BubbleLogger logger, + BubblePositioner positioner, + @ShellMainThread ShellExecutor mainExecutor) { + return new BubbleData(context, logger, positioner, mainExecutor); + } + // Note: Handler needed for LauncherApps.register @WMSingleton @Provides static BubbleController provideBubbleController(Context context, + ShellController shellController, + BubbleData data, FloatingContentCoordinator floatingContentCoordinator, IStatusBarService statusBarService, WindowManager windowManager, @@ -115,8 +144,9 @@ public abstract class WMShellModule { UserManager userManager, LauncherApps launcherApps, TaskStackListenerImpl taskStackListener, - UiEventLogger uiEventLogger, + BubbleLogger logger, ShellTaskOrganizer organizer, + BubblePositioner positioner, DisplayController displayController, @DynamicOverride Optional<OneHandedController> oneHandedOptional, DragAndDropController dragAndDropController, @@ -125,11 +155,12 @@ public abstract class WMShellModule { @ShellBackgroundThread ShellExecutor bgExecutor, TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue) { - return BubbleController.create(context, null /* synchronizer */, - floatingContentCoordinator, statusBarService, windowManager, - windowManagerShellWrapper, userManager, launcherApps, taskStackListener, - uiEventLogger, organizer, displayController, oneHandedOptional, - dragAndDropController, mainExecutor, mainHandler, bgExecutor, + return new BubbleController(context, shellController, data, null /* synchronizer */, + floatingContentCoordinator, + new BubbleDataRepository(context, launcherApps, mainExecutor), + statusBarService, windowManager, windowManagerShellWrapper, userManager, + launcherApps, logger, taskStackListener, organizer, positioner, displayController, + oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor, taskViewTransitions, syncQueue); } @@ -176,12 +207,14 @@ public abstract class WMShellModule { @Provides @DynamicOverride static OneHandedController provideOneHandedController(Context context, + ShellController shellController, WindowManager windowManager, DisplayController displayController, DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger, InteractionJankMonitor jankMonitor, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler) { - return OneHandedController.create(context, windowManager, displayController, displayLayout, - taskStackListener, jankMonitor, uiEventLogger, mainExecutor, mainHandler); + return OneHandedController.create(context, shellController, windowManager, + displayController, displayLayout, taskStackListener, jankMonitor, uiEventLogger, + mainExecutor, mainHandler); } // @@ -213,7 +246,8 @@ public abstract class WMShellModule { @WMSingleton @Provides - static Optional<Pip> providePip(Context context, DisplayController displayController, + static Optional<Pip> providePip(Context context, + ShellController shellController, DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState, PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, @@ -225,7 +259,7 @@ public abstract class WMShellModule { PipParamsChangedForwarder pipParamsChangedForwarder, Optional<OneHandedController> oneHandedController, @ShellMainThread ShellExecutor mainExecutor) { - return Optional.ofNullable(PipController.create(context, displayController, + return Optional.ofNullable(PipController.create(context, shellController, displayController, pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md index 68f970ff48df..0dd50b1bee68 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md @@ -52,4 +52,14 @@ For example, you might have: call, and the callback posts to the main SysUI thread Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently -necessary to maintain proper threading and logic isolation.
\ No newline at end of file +necessary to maintain proper threading and logic isolation. + +## Configuration changes & other SysUI events + +Aside from direct calls into Shell controllers for exposed features, the Shell also receives +common event callbacks from SysUI via the `ShellController`. This includes things like: + +- Configuration changes +- TODO: Shell init +- TODO: Shell command +- TODO: Keyguard events
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java index edeff6e37182..03351871caad 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDrop.java @@ -16,8 +16,6 @@ package com.android.wm.shell.draganddrop; -import android.content.res.Configuration; - import com.android.wm.shell.common.annotations.ExternalThread; /** @@ -25,10 +23,4 @@ import com.android.wm.shell.common.annotations.ExternalThread; */ @ExternalThread public interface DragAndDrop { - - /** Called when the theme changes. */ - void onThemeChanged(); - - /** Called when the configuration changes. */ - void onConfigChanged(Configuration newConfig); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java index 95de2dc61a43..0d0961c41a87 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java @@ -60,6 +60,8 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.sysui.ConfigurationChangeListener; +import com.android.wm.shell.sysui.ShellController; import java.util.ArrayList; import java.util.Optional; @@ -68,11 +70,12 @@ import java.util.Optional; * Handles the global drag and drop handling for the Shell. */ public class DragAndDropController implements DisplayController.OnDisplaysChangedListener, - View.OnDragListener { + View.OnDragListener, ConfigurationChangeListener { private static final String TAG = DragAndDropController.class.getSimpleName(); private final Context mContext; + private final ShellController mShellController; private final DisplayController mDisplayController; private final DragAndDropEventLogger mLogger; private final IconProvider mIconProvider; @@ -92,9 +95,14 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange void onDragStarted(); } - public DragAndDropController(Context context, DisplayController displayController, - UiEventLogger uiEventLogger, IconProvider iconProvider, ShellExecutor mainExecutor) { + public DragAndDropController(Context context, + ShellController shellController, + DisplayController displayController, + UiEventLogger uiEventLogger, + IconProvider iconProvider, + ShellExecutor mainExecutor) { mContext = context; + mShellController = shellController; mDisplayController = displayController; mLogger = new DragAndDropEventLogger(uiEventLogger); mIconProvider = iconProvider; @@ -109,6 +117,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange public void initialize(Optional<SplitScreenController> splitscreen) { mSplitScreen = splitscreen.orElse(null); mDisplayController.addDisplayWindowListener(this); + mShellController.addConfigurationChangeListener(this); } /** Adds a listener to be notified of drag and drop events. */ @@ -310,13 +319,15 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange return mimeTypes; } - private void onThemeChange() { + @Override + public void onThemeChanged() { for (int i = 0; i < mDisplayDropTargets.size(); i++) { mDisplayDropTargets.get(i).dragLayout.onThemeChange(); } } - private void onConfigChanged(Configuration newConfig) { + @Override + public void onConfigurationChanged(Configuration newConfig) { for (int i = 0; i < mDisplayDropTargets.size(); i++) { mDisplayDropTargets.get(i).dragLayout.onConfigChanged(newConfig); } @@ -344,19 +355,6 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange } private class DragAndDropImpl implements DragAndDrop { - - @Override - public void onThemeChanged() { - mMainExecutor.execute(() -> { - DragAndDropController.this.onThemeChange(); - }); - } - - @Override - public void onConfigChanged(Configuration newConfig) { - mMainExecutor.execute(() -> { - DragAndDropController.this.onConfigChanged(newConfig); - }); - } + // TODO: To be removed } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java index 60123ab97fd7..dd1c8d6d49e1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java @@ -16,21 +16,11 @@ package com.android.wm.shell.hidedisplaycutout; -import android.content.res.Configuration; - -import androidx.annotation.NonNull; - import com.android.wm.shell.common.annotations.ExternalThread; -import java.io.PrintWriter; - /** * Interface to engage hide display cutout feature. */ @ExternalThread public interface HideDisplayCutout { - /** - * Notifies {@link Configuration} changed. - */ - void onConfigurationChanged(Configuration newConfig); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java index 23f76ca5f6ae..b091ab8c692c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java @@ -19,7 +19,6 @@ package com.android.wm.shell.hidedisplaycutout; import android.content.Context; import android.content.res.Configuration; import android.os.SystemProperties; -import android.util.Slog; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -27,17 +26,19 @@ import androidx.annotation.VisibleForTesting; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.sysui.ConfigurationChangeListener; +import com.android.wm.shell.sysui.ShellController; import java.io.PrintWriter; -import java.util.concurrent.TimeUnit; /** * Manages the hide display cutout status. */ -public class HideDisplayCutoutController { +public class HideDisplayCutoutController implements ConfigurationChangeListener { private static final String TAG = "HideDisplayCutoutController"; private final Context mContext; + private final ShellController mShellController; private final HideDisplayCutoutOrganizer mOrganizer; private final ShellExecutor mMainExecutor; private final HideDisplayCutoutImpl mImpl = new HideDisplayCutoutImpl(); @@ -49,8 +50,9 @@ public class HideDisplayCutoutController { * supported. */ @Nullable - public static HideDisplayCutoutController create( - Context context, DisplayController displayController, ShellExecutor mainExecutor) { + public static HideDisplayCutoutController create(Context context, + ShellController shellController, DisplayController displayController, + ShellExecutor mainExecutor) { // The SystemProperty is set for devices that support this feature and is used to control // whether to create the HideDisplayCutout instance. // It's defined in the device.mk (e.g. device/google/crosshatch/device.mk). @@ -60,15 +62,17 @@ public class HideDisplayCutoutController { HideDisplayCutoutOrganizer organizer = new HideDisplayCutoutOrganizer(context, displayController, mainExecutor); - return new HideDisplayCutoutController(context, organizer, mainExecutor); + return new HideDisplayCutoutController(context, shellController, organizer, mainExecutor); } - HideDisplayCutoutController(Context context, HideDisplayCutoutOrganizer organizer, - ShellExecutor mainExecutor) { + HideDisplayCutoutController(Context context, ShellController shellController, + HideDisplayCutoutOrganizer organizer, ShellExecutor mainExecutor) { mContext = context; + mShellController = shellController; mOrganizer = organizer; mMainExecutor = mainExecutor; updateStatus(); + mShellController.addConfigurationChangeListener(this); } public HideDisplayCutout asHideDisplayCutout() { @@ -94,7 +98,8 @@ public class HideDisplayCutoutController { } } - private void onConfigurationChanged(Configuration newConfig) { + @Override + public void onConfigurationChanged(Configuration newConfig) { updateStatus(); } @@ -109,11 +114,6 @@ public class HideDisplayCutoutController { } private class HideDisplayCutoutImpl implements HideDisplayCutout { - @Override - public void onConfigurationChanged(Configuration newConfig) { - mMainExecutor.execute(() -> { - HideDisplayCutoutController.this.onConfigurationChanged(newConfig); - }); - } + // TODO: To be removed } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java index b00182f36cc8..ee99f327f742 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java @@ -16,7 +16,6 @@ package com.android.wm.shell.onehanded; -import android.content.res.Configuration; import android.os.SystemProperties; import com.android.wm.shell.common.annotations.ExternalThread; @@ -83,11 +82,6 @@ public interface OneHanded { void registerTransitionCallback(OneHandedTransitionCallback callback); /** - * Receive onConfigurationChanged() events - */ - void onConfigChanged(Configuration newConfig); - - /** * Notifies when user switch complete */ void onUserSwitch(int userId); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 1d8ac2b576e9..ea2d50851dcc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -28,12 +28,10 @@ import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE; import android.annotation.BinderThread; import android.content.ComponentName; import android.content.Context; -import android.content.om.IOverlayManager; import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Rect; import android.os.Handler; -import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.Settings; import android.util.Slog; @@ -56,6 +54,8 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.annotations.ExternalThread; +import com.android.wm.shell.sysui.ConfigurationChangeListener; +import com.android.wm.shell.sysui.ShellController; import java.io.PrintWriter; @@ -63,7 +63,7 @@ import java.io.PrintWriter; * Manages and manipulates the one handed states, transitions, and gesture for phones. */ public class OneHandedController implements RemoteCallable<OneHandedController>, - DisplayChangeController.OnDisplayChangingListener { + DisplayChangeController.OnDisplayChangingListener, ConfigurationChangeListener { private static final String TAG = "OneHandedController"; private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE = @@ -83,6 +83,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, private Context mContext; + private final ShellController mShellController; private final AccessibilityManager mAccessibilityManager; private final DisplayController mDisplayController; private final OneHandedSettingsUtil mOneHandedSettingsUtil; @@ -92,7 +93,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, private final OneHandedState mState; private final OneHandedTutorialHandler mTutorialHandler; private final TaskStackListenerImpl mTaskStackListener; - private final IOverlayManager mOverlayManager; private final ShellExecutor mMainExecutor; private final Handler mMainHandler; private final OneHandedImpl mImpl = new OneHandedImpl(); @@ -191,8 +191,9 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, * Creates {@link OneHandedController}, returns {@code null} if the feature is not supported. */ public static OneHandedController create( - Context context, WindowManager windowManager, DisplayController displayController, - DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener, + Context context, ShellController shellController, WindowManager windowManager, + DisplayController displayController, DisplayLayout displayLayout, + TaskStackListenerImpl taskStackListener, InteractionJankMonitor jankMonitor, UiEventLogger uiEventLogger, ShellExecutor mainExecutor, Handler mainHandler) { OneHandedSettingsUtil settingsUtil = new OneHandedSettingsUtil(); @@ -210,16 +211,15 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, context, displayLayout, settingsUtil, animationController, tutorialHandler, jankMonitor, mainExecutor); OneHandedUiEventLogger oneHandedUiEventsLogger = new OneHandedUiEventLogger(uiEventLogger); - IOverlayManager overlayManager = IOverlayManager.Stub.asInterface( - ServiceManager.getService(Context.OVERLAY_SERVICE)); - return new OneHandedController(context, displayController, organizer, touchHandler, - tutorialHandler, settingsUtil, accessibilityUtil, timeoutHandler, oneHandedState, - jankMonitor, oneHandedUiEventsLogger, overlayManager, taskStackListener, + return new OneHandedController(context, shellController, displayController, organizer, + touchHandler, tutorialHandler, settingsUtil, accessibilityUtil, timeoutHandler, + oneHandedState, oneHandedUiEventsLogger, taskStackListener, mainExecutor, mainHandler); } @VisibleForTesting OneHandedController(Context context, + ShellController shellController, DisplayController displayController, OneHandedDisplayAreaOrganizer displayAreaOrganizer, OneHandedTouchHandler touchHandler, @@ -228,13 +228,12 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, OneHandedAccessibilityUtil oneHandedAccessibilityUtil, OneHandedTimeoutHandler timeoutHandler, OneHandedState state, - InteractionJankMonitor jankMonitor, OneHandedUiEventLogger uiEventsLogger, - IOverlayManager overlayManager, TaskStackListenerImpl taskStackListener, ShellExecutor mainExecutor, Handler mainHandler) { mContext = context; + mShellController = shellController; mOneHandedSettingsUtil = settingsUtil; mOneHandedAccessibilityUtil = oneHandedAccessibilityUtil; mDisplayAreaOrganizer = displayAreaOrganizer; @@ -242,7 +241,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, mTouchHandler = touchHandler; mState = state; mTutorialHandler = tutorialHandler; - mOverlayManager = overlayManager; mMainExecutor = mainExecutor; mMainHandler = mainHandler; mOneHandedUiEventLogger = uiEventsLogger; @@ -280,6 +278,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, mAccessibilityStateChangeListener); mState.addSListeners(mTutorialHandler); + mShellController.addConfigurationChangeListener(this); } public OneHanded asOneHanded() { @@ -595,7 +594,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, mLockedDisabled = locked && !enabled; } - private void onConfigChanged(Configuration newConfig) { + @Override + public void onConfigurationChanged(Configuration newConfig) { if (mTutorialHandler == null) { return; } @@ -751,13 +751,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, } @Override - public void onConfigChanged(Configuration newConfig) { - mMainExecutor.execute(() -> { - OneHandedController.this.onConfigChanged(newConfig); - }); - } - - @Override public void onUserSwitch(int userId) { mMainExecutor.execute(() -> { OneHandedController.this.onUserSwitch(userId); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index bbc47e47afc5..2ac112977ece 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -16,7 +16,6 @@ package com.android.wm.shell.pip; -import android.content.res.Configuration; import android.graphics.Rect; import com.android.wm.shell.common.annotations.ExternalThread; @@ -44,24 +43,6 @@ public interface Pip { } /** - * Called when configuration is changed. - */ - default void onConfigurationChanged(Configuration newConfig) { - } - - /** - * Called when display size or font size of settings changed - */ - default void onDensityOrFontScaleChanged() { - } - - /** - * Called when overlay package change invoked. - */ - default void onOverlayChanged() { - } - - /** * Called when SysUI state changed. * * @param isSysUiStateValid Is SysUI state valid or not. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 05a890fc65ed..51be2a534dd7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -315,7 +315,7 @@ public class PipTransition extends PipTransitionController { } @Override - public void onTransitionMerged(@NonNull IBinder transition) { + public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { if (transition != mExitTransition) { return; } @@ -328,7 +328,7 @@ public class PipTransition extends PipTransitionController { } // Unset exitTransition AFTER cancel so that finishResize knows we are merging. mExitTransition = null; - if (!cancelled) return; + if (!cancelled || aborted) return; final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo(); if (taskInfo != null) { startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(), diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 3000998f210d..5ae460268635 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -87,6 +87,8 @@ import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip.PipTransitionState; import com.android.wm.shell.pip.PipUtils; import com.android.wm.shell.protolog.ShellProtoLogGroup; +import com.android.wm.shell.sysui.ConfigurationChangeListener; +import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.transition.Transitions; import java.io.PrintWriter; @@ -100,7 +102,7 @@ import java.util.function.Consumer; * Manages the picture-in-picture (PIP) UI and states for Phones. */ public class PipController implements PipTransitionController.PipTransitionCallback, - RemoteCallable<PipController> { + RemoteCallable<PipController>, ConfigurationChangeListener { private static final String TAG = "PipController"; private Context mContext; @@ -119,6 +121,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb private TaskStackListenerImpl mTaskStackListener; private PipParamsChangedForwarder mPipParamsChangedForwarder; private Optional<OneHandedController> mOneHandedController; + private final ShellController mShellController; protected final PipImpl mImpl; private final Rect mTmpInsetBounds = new Rect(); @@ -290,13 +293,20 @@ public class PipController implements PipTransitionController.PipTransitionCallb * Instantiates {@link PipController}, returns {@code null} if the feature not supported. */ @Nullable - public static Pip create(Context context, DisplayController displayController, - PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, - PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState, - PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, - PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer, + public static Pip create(Context context, + ShellController shellController, + DisplayController displayController, + PipAppOpsListener pipAppOpsListener, + PipBoundsAlgorithm pipBoundsAlgorithm, + PipKeepClearAlgorithm pipKeepClearAlgorithm, + PipBoundsState pipBoundsState, + PipMotionHelper pipMotionHelper, + PipMediaController pipMediaController, + PhonePipMenuController phonePipMenuController, + PipTaskOrganizer pipTaskOrganizer, PipTransitionState pipTransitionState, - PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController, + PipTouchHandler pipTouchHandler, + PipTransitionController pipTransitionController, WindowManagerShellWrapper windowManagerShellWrapper, TaskStackListenerImpl taskStackListener, PipParamsChangedForwarder pipParamsChangedForwarder, @@ -308,9 +318,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb return null; } - return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm, - pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController, - phonePipMenuController, pipTaskOrganizer, pipTransitionState, + return new PipController(context, shellController, displayController, pipAppOpsListener, + pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, + pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState, pipTouchHandler, pipTransitionController, windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder, oneHandedController, mainExecutor) @@ -318,6 +328,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb } protected PipController(Context context, + ShellController shellController, DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, @@ -343,6 +354,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb } mContext = context; + mShellController = shellController; mImpl = new PipImpl(); mWindowManagerShellWrapper = windowManagerShellWrapper; mDisplayController = displayController; @@ -513,6 +525,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb } }); }); + + mShellController.addConfigurationChangeListener(this); } @Override @@ -525,18 +539,21 @@ public class PipController implements PipTransitionController.PipTransitionCallb return mMainExecutor; } - private void onConfigurationChanged(Configuration newConfig) { + @Override + public void onConfigurationChanged(Configuration newConfig) { mPipBoundsAlgorithm.onConfigurationChanged(mContext); mTouchHandler.onConfigurationChanged(); mPipBoundsState.onConfigurationChanged(); } - private void onDensityOrFontScaleChanged() { + @Override + public void onDensityOrFontScaleChanged() { mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext); onPipResourceDimensionsChanged(); } - private void onOverlayChanged() { + @Override + public void onThemeChanged() { mTouchHandler.onOverlayChanged(); onDisplayChanged(new DisplayLayout(mContext, mContext.getDisplay()), false /* saveRestoreSnapFraction */); @@ -923,27 +940,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public void onConfigurationChanged(Configuration newConfig) { - mMainExecutor.execute(() -> { - PipController.this.onConfigurationChanged(newConfig); - }); - } - - @Override - public void onDensityOrFontScaleChanged() { - mMainExecutor.execute(() -> { - PipController.this.onDensityOrFontScaleChanged(); - }); - } - - @Override - public void onOverlayChanged() { - mMainExecutor.execute(() -> { - PipController.this.onOverlayChanged(); - }); - } - - @Override public void onSystemUiStateChanged(boolean isSysUiStateValid, int flag) { mMainExecutor.execute(() -> { PipController.this.onSystemUiStateChanged(isSysUiStateValid, flag); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java index fa48def9c7d7..a24d9618032d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java @@ -49,6 +49,8 @@ import com.android.wm.shell.pip.PipParamsChangedForwarder; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.protolog.ShellProtoLogGroup; +import com.android.wm.shell.sysui.ConfigurationChangeListener; +import com.android.wm.shell.sysui.ShellController; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -61,7 +63,8 @@ import java.util.Set; */ public class TvPipController implements PipTransitionController.PipTransitionCallback, TvPipBoundsController.PipBoundsListener, TvPipMenuController.Delegate, - TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener { + TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener, + ConfigurationChangeListener { private static final String TAG = "TvPipController"; static final boolean DEBUG = false; @@ -93,6 +96,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal private final Context mContext; + private final ShellController mShellController; private final TvPipBoundsState mTvPipBoundsState; private final TvPipBoundsAlgorithm mTvPipBoundsAlgorithm; private final TvPipBoundsController mTvPipBoundsController; @@ -117,6 +121,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal public static Pip create( Context context, + ShellController shellController, TvPipBoundsState tvPipBoundsState, TvPipBoundsAlgorithm tvPipBoundsAlgorithm, TvPipBoundsController tvPipBoundsController, @@ -133,6 +138,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal ShellExecutor mainExecutor) { return new TvPipController( context, + shellController, tvPipBoundsState, tvPipBoundsAlgorithm, tvPipBoundsController, @@ -151,6 +157,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal private TvPipController( Context context, + ShellController shellController, TvPipBoundsState tvPipBoundsState, TvPipBoundsAlgorithm tvPipBoundsAlgorithm, TvPipBoundsController tvPipBoundsController, @@ -167,6 +174,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal ShellExecutor mainExecutor) { mContext = context; mMainExecutor = mainExecutor; + mShellController = shellController; mTvPipBoundsState = tvPipBoundsState; mTvPipBoundsState.setDisplayId(context.getDisplayId()); @@ -193,9 +201,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal registerTaskStackListenerCallback(taskStackListener); registerWmShellPinnedStackListener(wmShell); displayController.addDisplayWindowListener(this); + + mShellController.addConfigurationChangeListener(this); } - private void onConfigurationChanged(Configuration newConfig) { + @Override + public void onConfigurationChanged(Configuration newConfig) { if (DEBUG) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: onConfigurationChanged(), state=%s", TAG, stateToName(mState)); @@ -669,13 +680,6 @@ public class TvPipController implements PipTransitionController.PipTransitionCal private class TvPipImpl implements Pip { @Override - public void onConfigurationChanged(Configuration newConfig) { - mMainExecutor.execute(() -> { - TvPipController.this.onConfigurationChanged(newConfig); - }); - } - - @Override public void registerSessionListenerForCurrentUser() { mMainExecutor.execute(() -> { TvPipController.this.registerSessionListenerForCurrentUser(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java index d04c34916256..b2961518b66a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java @@ -26,6 +26,8 @@ import com.android.internal.protolog.common.IProtoLogGroup; public enum ShellProtoLogGroup implements IProtoLogGroup { // NOTE: Since we enable these from the same WM ShellCommand, these names should not conflict // with those in the framework ProtoLogGroup + WM_SHELL_INIT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true, + Consts.TAG_WM_SHELL), WM_SHELL_TASK_ORG(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM_SHELL), WM_SHELL_TRANSITIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true, @@ -38,10 +40,12 @@ public enum ShellProtoLogGroup implements IProtoLogGroup { "ShellBackPreview"), WM_SHELL_RECENT_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM_SHELL), - WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, - false, Consts.TAG_WM_SHELL), + WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM_SHELL), WM_SHELL_SPLIT_SCREEN(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM_SHELL), + WM_SHELL_SYSUI_EVENTS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM_SHELL), TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest"); private final boolean mEnabled; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java index e7ec15e70c11..b0080b24c609 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java @@ -45,6 +45,11 @@ class MainStage extends StageTaskListener { iconProvider); } + @Override + void dismiss(WindowContainerTransaction wct, boolean toTop) { + deactivate(wct, toTop); + } + boolean isActive() { return mIsActive; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java index 8639b36faf4c..86efbe0af79c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java @@ -42,6 +42,11 @@ class SideStage extends StageTaskListener { iconProvider); } + @Override + void dismiss(WindowContainerTransaction wct, boolean toTop) { + removeAllTasks(wct, toTop); + } + boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) { if (mChildrenTaskInfo.size() == 0) return false; wct.reparentTasks( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 47bfaa64c831..21bea4674805 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -18,16 +18,12 @@ package com.android.wm.shell.splitscreen; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; @@ -66,7 +62,6 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; import com.android.internal.protolog.common.ProtoLog; -import com.android.internal.util.ArrayUtils; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; @@ -104,18 +99,18 @@ import java.util.concurrent.Executor; */ // TODO(b/198577848): Implement split screen flicker test to consolidate CUJ of split screen. public class SplitScreenController implements DragAndDropPolicy.Starter, - RemoteCallable<SplitScreenController>, ShellTaskOrganizer.FocusListener { + RemoteCallable<SplitScreenController> { private static final String TAG = SplitScreenController.class.getSimpleName(); - static final int EXIT_REASON_UNKNOWN = 0; - static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1; - static final int EXIT_REASON_APP_FINISHED = 2; - static final int EXIT_REASON_DEVICE_FOLDED = 3; - static final int EXIT_REASON_DRAG_DIVIDER = 4; - static final int EXIT_REASON_RETURN_HOME = 5; - static final int EXIT_REASON_ROOT_TASK_VANISHED = 6; - static final int EXIT_REASON_SCREEN_LOCKED = 7; - static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8; + public static final int EXIT_REASON_UNKNOWN = 0; + public static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1; + public static final int EXIT_REASON_APP_FINISHED = 2; + public static final int EXIT_REASON_DEVICE_FOLDED = 3; + public static final int EXIT_REASON_DRAG_DIVIDER = 4; + public static final int EXIT_REASON_RETURN_HOME = 5; + public static final int EXIT_REASON_ROOT_TASK_VANISHED = 6; + public static final int EXIT_REASON_SCREEN_LOCKED = 7; + public static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8; public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9; @IntDef(value = { EXIT_REASON_UNKNOWN, @@ -152,8 +147,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, // outside the bounds of the roots by being reparented into a higher level fullscreen container private SurfaceControl mSplitTasksContainerLayer; - private ActivityManager.RunningTaskInfo mFocusingTaskInfo; - public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, Context context, RootTaskDisplayAreaOrganizer rootTDAOrganizer, @@ -175,7 +168,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mLogger = new SplitscreenEventLogger(); mIconProvider = iconProvider; mRecentTasksOptional = recentTasks; - mTaskOrganizer.addFocusListener(this); } public SplitScreen asSplitScreen() { @@ -192,11 +184,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return mMainExecutor; } - @Override - public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) { - mFocusingTaskInfo = taskInfo; - } - public void onOrganizerRegistered() { if (mStageCoordinator == null) { // TODO: Multi-display @@ -215,6 +202,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return mStageCoordinator; } + public ActivityManager.RunningTaskInfo getFocusingTaskInfo() { + return mStageCoordinator.getFocusingTaskInfo(); + } + + public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { + return mStageCoordinator.isValidToEnterSplitScreen(taskInfo); + } + @Nullable public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) { if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) { @@ -230,12 +225,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, && mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED; } - public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { - return taskInfo.supportsMultiWindow - && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()) - && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()); - } - public @SplitPosition int getSplitPosition(int taskId) { return mStageCoordinator.getSplitPosition(taskId); } @@ -472,8 +461,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return Objects.equals(launchingActivity, pairedActivity); } - if (mFocusingTaskInfo != null && isValidToEnterSplitScreen(mFocusingTaskInfo)) { - return Objects.equals(mFocusingTaskInfo.baseIntent.getComponent(), launchingActivity); + final ActivityManager.RunningTaskInfo taskInfo = getFocusingTaskInfo(); + if (taskInfo != null && isValidToEnterSplitScreen(taskInfo)) { + return Objects.equals(taskInfo.baseIntent.getComponent(), launchingActivity); } return false; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java index e55729a883e0..056cd5813861 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java @@ -246,7 +246,9 @@ class SplitScreenTransitions { return true; } - void onTransitionMerged(@NonNull IBinder transition) { + void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { + if (aborted) return; + // Once a pending enter transition got merged, make sure to append the reset of finishing // operations to the finish transition. if (transition == mPendingEnter) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 2764f96022b9..2229e26b9343 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -35,6 +35,8 @@ import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER; +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; @@ -98,6 +100,7 @@ import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; import com.android.internal.protolog.common.ProtoLog; +import com.android.internal.util.ArrayUtils; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; @@ -138,7 +141,7 @@ import java.util.Optional; */ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler, - ShellTaskOrganizer.TaskListener { + ShellTaskOrganizer.TaskListener, ShellTaskOrganizer.FocusListener { private static final String TAG = StageCoordinator.class.getSimpleName(); @@ -176,6 +179,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private final Rect mTempRect1 = new Rect(); private final Rect mTempRect2 = new Rect(); + private ActivityManager.RunningTaskInfo mFocusingTaskInfo; + /** * A single-top root task which the split divider attached to. */ @@ -189,6 +194,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private boolean mShouldUpdateRecents; private boolean mExitSplitScreenOnHide; private boolean mIsDividerRemoteAnimating; + private boolean mIsExiting; private boolean mResizingSplits; /** The target stage to dismiss to when unlock after folded. */ @@ -254,6 +260,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mDisplayController.addDisplayWindowListener(this); mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId)); transitions.addHandler(this); + mTaskOrganizer.addFocusListener(this); } @VisibleForTesting @@ -734,7 +741,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void applyExitSplitScreen(@Nullable StageTaskListener childrenToTop, WindowContainerTransaction wct, @ExitReason int exitReason) { - if (!mMainStage.isActive()) return; + if (!mMainStage.isActive() || mIsExiting) return; mRecentTasks.ifPresent(recentTasks -> { // Notify recents if we are exiting in a way that breaks the pair, and disable further @@ -746,21 +753,45 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, }); mShouldUpdateRecents = false; - // When the exit split-screen is caused by one of the task enters auto pip, - // we want the tasks to be put to bottom instead of top, otherwise it will end up - // a fullscreen plus a pinned task instead of pinned only at the end of the transition. - final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP; - mSideStage.removeAllTasks(wct, !fromEnteringPip && mSideStage == childrenToTop); - mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop); - wct.reorder(mRootTaskInfo.token, false /* onTop */); - mTaskOrganizer.applyTransaction(wct); + if (childrenToTop == null) { + mSideStage.removeAllTasks(wct, false /* toTop */); + mMainStage.deactivate(wct, false /* toTop */); + wct.reorder(mRootTaskInfo.token, false /* onTop */); + onTransitionAnimationComplete(); + } else { + // Expand to top side split as full screen for fading out decor animation and dismiss + // another side split(Moving its children to bottom). + mIsExiting = true; + final StageTaskListener tempFullStage = childrenToTop; + final StageTaskListener dismissStage = mMainStage == childrenToTop + ? mSideStage : mMainStage; + tempFullStage.resetBounds(wct); + wct.setSmallestScreenWidthDp(tempFullStage.mRootTaskInfo.token, + mRootTaskInfo.configuration.smallestScreenWidthDp); + dismissStage.dismiss(wct, false /* toTop */); + } + mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { t.setWindowCrop(mMainStage.mRootLeash, null) .setWindowCrop(mSideStage.mRootLeash, null); + t.setPosition(mMainStage.mRootLeash, 0, 0) + .setPosition(mSideStage.mRootLeash, 0, 0); setDividerVisibility(false, t); + + // In this case, exit still under progress, fade out the split decor after first WCT + // done and do remaining WCT after animation finished. + if (childrenToTop != null) { + childrenToTop.fadeOutDecor(() -> { + WindowContainerTransaction finishedWCT = new WindowContainerTransaction(); + mIsExiting = false; + childrenToTop.dismiss(finishedWCT, true /* toTop */); + wct.reorder(mRootTaskInfo.token, false /* toTop */); + mTaskOrganizer.applyTransaction(finishedWCT); + onTransitionAnimationComplete(); + }); + } }); - onTransitionAnimationComplete(); Slog.i(TAG, "applyExitSplitScreen, reason = " + exitReasonToString(exitReason)); // Log the exit if (childrenToTop != null) { @@ -930,9 +961,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } - private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) { - exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage, - EXIT_REASON_CHILD_TASK_ENTER_PIP); + private void onStageChildTaskEnterPip() { + // When the exit split-screen is caused by one of the task enters auto pip, + // we want both tasks to be put to bottom instead of top, otherwise it will end up + // a fullscreen plus a pinned task instead of pinned only at the end of the transition. + exitSplitScreen(null, EXIT_REASON_CHILD_TASK_ENTER_PIP); } private void updateRecentTasksSplitPair() { @@ -1178,21 +1211,42 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void onStageHasChildrenChanged(StageListenerImpl stageListener) { final boolean hasChildren = stageListener.mHasChildren; final boolean isSideStage = stageListener == mSideStageListener; - if (!hasChildren) { + if (!hasChildren && !mIsExiting) { if (isSideStage && mMainStageListener.mVisible) { // Exit to main stage if side stage no longer has children. - exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED); + if (ENABLE_SHELL_TRANSITIONS) { + exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED); + } else { + mSplitLayout.flingDividerToDismiss( + mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT, + EXIT_REASON_APP_FINISHED); + } } else if (!isSideStage && mSideStageListener.mVisible) { // Exit to side stage if main stage no longer has children. - exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED); + if (ENABLE_SHELL_TRANSITIONS) { + exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED); + } else { + mSplitLayout.flingDividerToDismiss( + mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT, + EXIT_REASON_APP_FINISHED); + } } } else if (isSideStage && !mMainStage.isActive()) { - final WindowContainerTransaction wct = new WindowContainerTransaction(); - mSplitLayout.init(); - prepareEnterSplitScreen(wct); - mSyncQueue.queue(wct); - mSyncQueue.runInSync(t -> - updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */)); + if (mFocusingTaskInfo != null && !isValidToEnterSplitScreen(mFocusingTaskInfo)) { + final WindowContainerTransaction wct = new WindowContainerTransaction(); + mSideStage.removeAllTasks(wct, true); + wct.reorder(mRootTaskInfo.token, false /* onTop */); + mTaskOrganizer.applyTransaction(wct); + Slog.i(TAG, "cancel entering split screen, reason = " + + exitReasonToString(EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW)); + } else { + final WindowContainerTransaction wct = new WindowContainerTransaction(); + mSplitLayout.init(); + prepareEnterSplitScreen(wct); + mSyncQueue.queue(wct); + mSyncQueue.runInSync(t -> + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */)); + } } if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) { mShouldUpdateRecents = true; @@ -1207,13 +1261,28 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } + boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) { + return taskInfo.supportsMultiWindow + && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType()) + && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode()); + } + + ActivityManager.RunningTaskInfo getFocusingTaskInfo() { + return mFocusingTaskInfo; + } + @Override - public void onSnappedToDismiss(boolean bottomOrRight) { + public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) { + mFocusingTaskInfo = taskInfo; + } + + @Override + public void onSnappedToDismiss(boolean bottomOrRight, int reason) { final boolean mainStageToTop = bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT; if (!ENABLE_SHELL_TRANSITIONS) { - exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, EXIT_REASON_DRAG_DIVIDER); + exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, reason); return; } @@ -1535,8 +1604,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override - public void onTransitionMerged(@NonNull IBinder transition) { - mSplitTransitions.onTransitionMerged(transition); + public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { + mSplitTransitions.onTransitionConsumed(transition, aborted); } @Override @@ -1615,7 +1684,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** Called to clean-up state and do house-keeping after the animation is done. */ public void onTransitionAnimationComplete() { // If still playing, let it finish. - if (!mMainStage.isActive()) { + if (!mMainStage.isActive() && !mIsExiting) { // Update divider state after animation so that it is still around and positioned // properly for the animation itself. mSplitLayout.release(); @@ -1911,8 +1980,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override - public void onChildTaskEnterPip(int taskId) { - StageCoordinator.this.onStageChildTaskEnterPip(this, taskId); + public void onChildTaskEnterPip() { + StageCoordinator.this.onStageChildTaskEnterPip(); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index d17ff7aff667..f6dc68be946a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -71,7 +71,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); - void onChildTaskEnterPip(int taskId); + void onChildTaskEnterPip(); void onRootTaskVanished(); @@ -103,6 +103,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this); } + /** + * General function for dismiss this stage. + */ + void dismiss(WindowContainerTransaction wct, boolean toTop) {} + int getChildCount() { return mChildrenTaskInfo.size(); } @@ -255,7 +260,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { return; } if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) { - mCallbacks.onChildTaskEnterPip(taskId); + mCallbacks.onChildTaskEnterPip(); } sendStatusChanged(); } else { @@ -297,6 +302,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } } + void fadeOutDecor(Runnable finishedCallback) { + if (mSplitDecorManager != null) { + mSplitDecorManager.fadeOutDecor(finishedCallback); + } else { + finishedCallback.run(); + } + } + void addTask(ActivityManager.RunningTaskInfo task, WindowContainerTransaction wct) { // Clear overridden bounds and windowing mode to make sure the child task can inherit // windowing mode and bounds from split root. @@ -330,6 +343,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } } + void resetBounds(WindowContainerTransaction wct) { + wct.setBounds(mRootTaskInfo.token, null); + wct.setAppBounds(mRootTaskInfo.token, null); + } + void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener, @StageType int stage) { for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ConfigurationChangeListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ConfigurationChangeListener.java new file mode 100644 index 000000000000..2fca8f0ecc76 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ConfigurationChangeListener.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.sysui; + +import android.content.res.Configuration; + +/** + * Callbacks for when the configuration changes. + */ +public interface ConfigurationChangeListener { + + /** + * Called when a configuration changes. This precedes all the following callbacks. + */ + default void onConfigurationChanged(Configuration newConfiguration) {} + + /** + * Convenience method to the above, called when the density or font scale changes. + */ + default void onDensityOrFontScaleChanged() {} + + /** + * Convenience method to the above, called when the smallest screen width changes. + */ + default void onSmallestScreenWidthChanged() {} + + /** + * Convenience method to the above, called when the system theme changes, including dark/light + * UI_MODE changes. + */ + default void onThemeChanged() {} + + /** + * Convenience method to the above, called when the local list or layout direction changes. + */ + default void onLocaleOrLayoutDirectionChanged() {} +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java new file mode 100644 index 000000000000..28a30f4905a5 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.sysui; + +import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS; +import static android.content.pm.ActivityInfo.CONFIG_FONT_SCALE; +import static android.content.pm.ActivityInfo.CONFIG_LAYOUT_DIRECTION; +import static android.content.pm.ActivityInfo.CONFIG_LOCALE; +import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; +import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; + +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SYSUI_EVENTS; + +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; + +import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.annotations.ExternalThread; + +import java.io.PrintWriter; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Handles event callbacks from SysUI that can be used within the Shell. + */ +public class ShellController { + private static final String TAG = ShellController.class.getSimpleName(); + + private final ShellExecutor mMainExecutor; + private final ShellInterfaceImpl mImpl = new ShellInterfaceImpl(); + + private final CopyOnWriteArrayList<ConfigurationChangeListener> mListeners = + new CopyOnWriteArrayList<>(); + private Configuration mLastConfiguration; + + + public ShellController(ShellExecutor mainExecutor) { + mMainExecutor = mainExecutor; + } + + /** + * Returns the external interface to this controller. + */ + public ShellInterface asShell() { + return mImpl; + } + + /** + * Adds a new configuration listener. The configuration change callbacks are not made in any + * particular order. + */ + public void addConfigurationChangeListener(ConfigurationChangeListener listener) { + mListeners.remove(listener); + mListeners.add(listener); + } + + /** + * Removes an existing configuration listener. + */ + public void removeConfigurationChangeListener(ConfigurationChangeListener listener) { + mListeners.remove(listener); + } + + @VisibleForTesting + void onConfigurationChanged(Configuration newConfig) { + // The initial config is send on startup and doesn't trigger listener callbacks + if (mLastConfiguration == null) { + mLastConfiguration = new Configuration(newConfig); + ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "Initial Configuration: %s", newConfig); + return; + } + + final int diff = newConfig.diff(mLastConfiguration); + ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "New configuration change: %s", newConfig); + ProtoLog.v(WM_SHELL_SYSUI_EVENTS, "\tchanges=%s", + Configuration.configurationDiffToString(diff)); + final boolean densityFontScaleChanged = (diff & CONFIG_FONT_SCALE) != 0 + || (diff & ActivityInfo.CONFIG_DENSITY) != 0; + final boolean smallestScreenWidthChanged = (diff & CONFIG_SMALLEST_SCREEN_SIZE) != 0; + final boolean themeChanged = (diff & CONFIG_ASSETS_PATHS) != 0 + || (diff & CONFIG_UI_MODE) != 0; + final boolean localOrLayoutDirectionChanged = (diff & CONFIG_LOCALE) != 0 + || (diff & CONFIG_LAYOUT_DIRECTION) != 0; + + // Update the last configuration and call listeners + mLastConfiguration.updateFrom(newConfig); + for (ConfigurationChangeListener listener : mListeners) { + listener.onConfigurationChanged(newConfig); + if (densityFontScaleChanged) { + listener.onDensityOrFontScaleChanged(); + } + if (smallestScreenWidthChanged) { + listener.onSmallestScreenWidthChanged(); + } + if (themeChanged) { + listener.onThemeChanged(); + } + if (localOrLayoutDirectionChanged) { + listener.onLocaleOrLayoutDirectionChanged(); + } + } + } + + public void dump(@NonNull PrintWriter pw, String prefix) { + final String innerPrefix = prefix + " "; + pw.println(prefix + TAG); + pw.println(innerPrefix + "mListeners=" + mListeners.size()); + pw.println(innerPrefix + "mLastConfiguration=" + mLastConfiguration); + } + + /** + * The interface for calls from outside the Shell, within the host process. + */ + @ExternalThread + private class ShellInterfaceImpl implements ShellInterface { + @Override + public void onConfigurationChanged(Configuration newConfiguration) { + mMainExecutor.execute(() -> + ShellController.this.onConfigurationChanged(newConfiguration)); + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java new file mode 100644 index 000000000000..a2d072cd7d88 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInterface.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.sysui; + +import android.content.res.Configuration; + +/** + * General interface for notifying the Shell of common SysUI events like configuration or keyguard + * changes. + * + * TODO: Move ShellInit and ShellCommandHandler into this interface + */ +public interface ShellInterface { + + /** + * Notifies the Shell that the configuration has changed. + */ + default void onConfigurationChanged(Configuration newConfiguration) {} +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java index 7234d559e153..11b453cb24a2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java @@ -274,7 +274,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { } @Override - public void onTransitionMerged(@NonNull IBinder transition) { + public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { MixedTransition mixed = null; for (int i = mActiveTransitions.size() - 1; i >= 0; --i) { if (mActiveTransitions.get(i).mTransition != transition) continue; @@ -283,7 +283,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { } if (mixed == null) return; if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) { - mPipHandler.onTransitionMerged(transition); + mPipHandler.onTransitionConsumed(transition, aborted); } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java index 3e2a0e635a75..ebaece2189aa 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java @@ -99,6 +99,8 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler { + " during unit tests"); } mRemote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb); + // assume that remote will apply the start transaction. + startTransaction.clear(); } catch (RemoteException e) { Log.e(Transitions.TAG, "Error running remote transition.", e); if (mRemote.asBinder() != null) { @@ -120,6 +122,11 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler { @Override public void onTransitionFinished(WindowContainerTransaction wct, SurfaceControl.Transaction sct) { + // We have merged, since we sent the transaction over binder, the one in this + // process won't be cleared if the remote applied it. We don't actually know if the + // remote applied the transaction, but applying twice will break surfaceflinger + // so just assume the worst-case and clear the local transaction. + t.clear(); mMainExecutor.execute( () -> finishCallback.onTransitionFinished(wct, null /* wctCB */)); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java index ece9f47e8788..b15c48cb5889 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java @@ -83,7 +83,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { } @Override - public void onTransitionMerged(@NonNull IBinder transition) { + public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { mRequestedRemotes.remove(transition); } @@ -139,6 +139,8 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { + " during unit tests"); } remote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb); + // assume that remote will apply the start transaction. + startTransaction.clear(); } catch (RemoteException e) { Log.e(Transitions.TAG, "Error running remote transition.", e); unhandleDeath(remote.asBinder(), finishCallback); @@ -162,6 +164,11 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { @Override public void onTransitionFinished(WindowContainerTransaction wct, SurfaceControl.Transaction sct) { + // We have merged, since we sent the transaction over binder, the one in this + // process won't be cleared if the remote applied it. We don't actually know if the + // remote applied the transaction, but applying twice will break surfaceflinger + // so just assume the worst-case and clear the local transaction. + t.clear(); mMainExecutor.execute(() -> { if (!mRequestedRemotes.containsKey(mergeTarget)) { Log.e(TAG, "Merged transition finished after it's mergeTarget (the " diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index de0f47fa0a6b..fa22c7ca94d2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -516,15 +516,20 @@ public class Transitions implements RemoteCallable<Transitions> { active.mMerged = true; active.mAborted = abort; if (active.mHandler != null) { - active.mHandler.onTransitionMerged(active.mToken); + active.mHandler.onTransitionConsumed(active.mToken, abort); } return; } - mActiveTransitions.get(activeIdx).mAborted = abort; + final ActiveTransition active = mActiveTransitions.get(activeIdx); + active.mAborted = abort; + if (active.mAborted && active.mHandler != null) { + // Notifies to clean-up the aborted transition. + active.mHandler.onTransitionConsumed(transition, true /* aborted */); + } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition animation finished (abort=%b), notifying core %s", abort, transition); // Merge all relevant transactions together - SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT; + SurfaceControl.Transaction fullFinish = active.mFinishT; for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) { final ActiveTransition toMerge = mActiveTransitions.get(iA); if (!toMerge.mMerged) break; @@ -553,6 +558,10 @@ public class Transitions implements RemoteCallable<Transitions> { while (mActiveTransitions.size() > activeIdx && mActiveTransitions.get(activeIdx).mAborted) { ActiveTransition aborted = mActiveTransitions.remove(activeIdx); + // Notifies to clean-up the aborted transition. + if (aborted.mHandler != null) { + aborted.mHandler.onTransitionConsumed(transition, true /* aborted */); + } mOrganizer.finishTransition(aborted.mToken, null /* wct */, null /* wctCB */); } if (mActiveTransitions.size() <= activeIdx) { @@ -735,9 +744,10 @@ public class Transitions implements RemoteCallable<Transitions> { /** * Called when a transition which was already "claimed" by this handler has been merged - * into another animation. Gives this handler a chance to clean-up any expectations. + * into another animation or has been aborted. Gives this handler a chance to clean-up any + * expectations. */ - default void onTransitionMerged(@NonNull IBinder transition) { } + default void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { } /** * Sets transition animation scale settings value to handler. diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java new file mode 100644 index 000000000000..ace8d365c7af --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.activityembedding.ActivityEmbeddingController; +import com.android.wm.shell.bubbles.BubbleController; +import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.DisplayInsetsController; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.draganddrop.DragAndDropController; +import com.android.wm.shell.freeform.FreeformTaskListener; +import com.android.wm.shell.fullscreen.FullscreenTaskListener; +import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer; +import com.android.wm.shell.pip.phone.PipTouchHandler; +import com.android.wm.shell.recents.RecentTasksController; +import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.startingsurface.StartingWindowController; +import com.android.wm.shell.transition.Transitions; +import com.android.wm.shell.unfold.UnfoldAnimationController; +import com.android.wm.shell.unfold.UnfoldTransitionHandler; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.Optional; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class ShellInitImplTest extends ShellTestCase { + + @Mock private DisplayController mDisplayController; + @Mock private DisplayImeController mDisplayImeController; + @Mock private DisplayInsetsController mDisplayInsetsController; + @Mock private DragAndDropController mDragAndDropController; + @Mock private ShellTaskOrganizer mShellTaskOrganizer; + @Mock private KidsModeTaskOrganizer mKidsModeTaskOrganizer; + @Mock private Optional<BubbleController> mBubblesOptional; + @Mock private Optional<SplitScreenController> mSplitScreenOptional; + @Mock private Optional<PipTouchHandler> mPipTouchHandlerOptional; + @Mock private FullscreenTaskListener mFullscreenTaskListener; + @Mock private Optional<UnfoldAnimationController> mUnfoldAnimationController; + @Mock private Optional<UnfoldTransitionHandler> mUnfoldTransitionHandler; + @Mock private Optional<FreeformTaskListener<?>> mFreeformTaskListenerOptional; + @Mock private Optional<RecentTasksController> mRecentTasks; + @Mock private Optional<ActivityEmbeddingController> mActivityEmbeddingController; + @Mock private Transitions mTransitions; + @Mock private StartingWindowController mStartingWindow; + @Mock private ShellExecutor mMainExecutor; + + private ShellInitImpl mImpl; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mImpl = new ShellInitImpl(mDisplayController, mDisplayImeController, + mDisplayInsetsController, mDragAndDropController, mShellTaskOrganizer, + mKidsModeTaskOrganizer, mBubblesOptional, mSplitScreenOptional, + mPipTouchHandlerOptional, mFullscreenTaskListener, mUnfoldAnimationController, + mUnfoldTransitionHandler, mFreeformTaskListenerOptional, mRecentTasks, + mActivityEmbeddingController, mTransitions, mStartingWindow, mMainExecutor); + } + + @Test + public void testAddInitCallbacks_expectCalledInOrder() { + ArrayList<Integer> results = new ArrayList<>(); + mImpl.addInitCallback(() -> { + results.add(1); + }, new Object()); + mImpl.addInitCallback(() -> { + results.add(2); + }, new Object()); + mImpl.addInitCallback(() -> { + results.add(3); + }, new Object()); + mImpl.init(); + assertTrue(results.get(0) == 1); + assertTrue(results.get(1) == 2); + assertTrue(results.get(2) == 3); + } + + @Test + public void testNoInitCallbacksAfterInit_expectException() { + mImpl.init(); + try { + mImpl.addInitCallback(() -> {}, new Object()); + fail("Expected exception when adding callback after init"); + } catch (IllegalArgumentException e) { + // Expected + } + } + + @Test + public void testDoubleInit_expectNoOp() { + ArrayList<Integer> results = new ArrayList<>(); + mImpl.addInitCallback(() -> { + results.add(1); + }, new Object()); + mImpl.init(); + assertTrue(results.size() == 1); + mImpl.init(); + assertTrue(results.size() == 1); + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java index f1e602fcf778..95725bbfd855 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java @@ -133,7 +133,7 @@ public class SplitLayoutTests extends ShellTestCase { mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget); waitDividerFlingFinished(); - verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false)); + verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false), anyInt()); } @Test @@ -145,7 +145,7 @@ public class SplitLayoutTests extends ShellTestCase { mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget); waitDividerFlingFinished(); - verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true)); + verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true), anyInt()); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java index 0b43163787f3..e209971998c8 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropControllerTest.java @@ -21,6 +21,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.DragEvent.ACTION_DRAG_STARTED; import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -48,6 +49,7 @@ import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.splitscreen.SplitScreenController; +import com.android.wm.shell.sysui.ShellController; import org.junit.Before; import org.junit.Test; @@ -66,24 +68,34 @@ public class DragAndDropControllerTest extends ShellTestCase { @Mock private Context mContext; - + @Mock + private ShellController mShellController; @Mock private DisplayController mDisplayController; - @Mock private UiEventLogger mUiEventLogger; - @Mock private DragAndDropController.DragAndDropListener mDragAndDropListener; + @Mock + private IconProvider mIconProvider; + @Mock + private ShellExecutor mMainExecutor; + @Mock + private SplitScreenController mSplitScreenController; private DragAndDropController mController; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); - mController = new DragAndDropController(mContext, mDisplayController, mUiEventLogger, - mock(IconProvider.class), mock(ShellExecutor.class)); - mController.initialize(Optional.of(mock(SplitScreenController.class))); + mController = new DragAndDropController(mContext, mShellController, mDisplayController, + mUiEventLogger, mIconProvider, mMainExecutor); + mController.initialize(Optional.of(mSplitScreenController)); + } + + @Test + public void instantiateController_registerConfigChangeListener() { + verify(mShellController, times(1)).addConfigurationChangeListener(any()); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java index 7ecd5020d56e..68e955e7cf7a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java @@ -16,7 +16,9 @@ package com.android.wm.shell.hidedisplaycutout; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.testing.AndroidTestingRunner; @@ -28,6 +30,7 @@ import androidx.test.platform.app.InstrumentationRegistry; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.sysui.ShellController; import org.junit.Before; import org.junit.Test; @@ -42,17 +45,25 @@ public class HideDisplayCutoutControllerTest extends ShellTestCase { private TestableContext mContext = new TestableContext( InstrumentationRegistry.getInstrumentation().getTargetContext(), null); - private HideDisplayCutoutController mHideDisplayCutoutController; + @Mock + private ShellController mShellController; @Mock private HideDisplayCutoutOrganizer mMockDisplayAreaOrganizer; @Mock private ShellExecutor mMockMainExecutor; + private HideDisplayCutoutController mHideDisplayCutoutController; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mHideDisplayCutoutController = new HideDisplayCutoutController( - mContext, mMockDisplayAreaOrganizer, mMockMainExecutor); + mContext, mShellController, mMockDisplayAreaOrganizer, mMockMainExecutor); + } + + @Test + public void instantiateController_registerConfigChangeListener() { + verify(mShellController, times(1)).addConfigurationChangeListener(any()); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 6a6db8aa3c04..958969deb564 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -30,10 +30,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.om.IOverlayManager; import android.graphics.Rect; import android.os.Handler; import android.os.UserHandle; @@ -41,16 +41,15 @@ import android.testing.AndroidTestingRunner; import android.util.ArrayMap; import android.view.Display; import android.view.Surface; -import android.view.SurfaceControl; import android.window.WindowContainerTransaction; import androidx.test.filters.SmallTest; -import com.android.internal.jank.InteractionJankMonitor; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.sysui.ShellController; import org.junit.Before; import org.junit.Test; @@ -71,6 +70,8 @@ public class OneHandedControllerTest extends OneHandedTestCase { OneHandedState mSpiedTransitionState; @Mock + ShellController mMockShellController; + @Mock DisplayLayout mDisplayLayout; @Mock DisplayController mMockDisplayController; @@ -87,16 +88,10 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Mock OneHandedUiEventLogger mMockUiEventLogger; @Mock - InteractionJankMonitor mMockJankMonitor; - @Mock - IOverlayManager mMockOverlayManager; - @Mock TaskStackListenerImpl mMockTaskStackListener; @Mock ShellExecutor mMockShellMainExecutor; @Mock - SurfaceControl mMockLeash; - @Mock Handler mMockShellMainHandler; final boolean mDefaultEnabled = true; @@ -132,6 +127,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mOneHandedAccessibilityUtil = new OneHandedAccessibilityUtil(mContext); mSpiedOneHandedController = spy(new OneHandedController( mContext, + mMockShellController, mMockDisplayController, mMockDisplayAreaOrganizer, mMockTouchHandler, @@ -140,9 +136,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mOneHandedAccessibilityUtil, mSpiedTimeoutHandler, mSpiedTransitionState, - mMockJankMonitor, mMockUiEventLogger, - mMockOverlayManager, mMockTaskStackListener, mMockShellMainExecutor, mMockShellMainHandler) @@ -150,6 +144,11 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test + public void testControllerRegistersConfigChangeListener() { + verify(mMockShellController, times(1)).addConfigurationChangeListener(any()); + } + + @Test public void testDefaultShouldNotInOneHanded() { // Assert default transition state is STATE_NONE assertThat(mSpiedTransitionState.getState()).isEqualTo(STATE_NONE); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java index dba1b8b86261..e6a8220e081b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java @@ -29,22 +29,19 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.om.IOverlayManager; import android.graphics.Rect; import android.os.Handler; -import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.util.ArrayMap; import android.view.Display; -import android.view.SurfaceControl; import androidx.test.filters.SmallTest; -import com.android.internal.jank.InteractionJankMonitor; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.sysui.ShellController; import org.junit.Before; import org.junit.Test; @@ -55,7 +52,6 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) public class OneHandedStateTest extends OneHandedTestCase { - private int mCurrentUser = UserHandle.myUserId(); Display mDisplay; DisplayLayout mDisplayLayout; @@ -65,6 +61,8 @@ public class OneHandedStateTest extends OneHandedTestCase { OneHandedState mSpiedState; @Mock + ShellController mMockShellController; + @Mock DisplayController mMockDisplayController; @Mock OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer; @@ -77,16 +75,10 @@ public class OneHandedStateTest extends OneHandedTestCase { @Mock OneHandedUiEventLogger mMockUiEventLogger; @Mock - InteractionJankMonitor mMockJankMonitor; - @Mock - IOverlayManager mMockOverlayManager; - @Mock TaskStackListenerImpl mMockTaskStackListener; @Mock ShellExecutor mMockShellMainExecutor; @Mock - SurfaceControl mMockLeash; - @Mock Handler mMockShellMainHandler; final boolean mDefaultEnabled = true; @@ -119,6 +111,7 @@ public class OneHandedStateTest extends OneHandedTestCase { mOneHandedAccessibilityUtil = new OneHandedAccessibilityUtil(mContext); mSpiedOneHandedController = spy(new OneHandedController( mContext, + mMockShellController, mMockDisplayController, mMockDisplayAreaOrganizer, mMockTouchHandler, @@ -127,9 +120,7 @@ public class OneHandedStateTest extends OneHandedTestCase { mOneHandedAccessibilityUtil, mSpiedTimeoutHandler, mSpiedState, - mMockJankMonitor, mMockUiEventLogger, - mMockOverlayManager, mMockTaskStackListener, mMockShellMainExecutor, mMockShellMainHandler) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index babc9707ef9c..827785bcc3e0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -54,6 +55,7 @@ import com.android.wm.shell.pip.PipSnapAlgorithm; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip.PipTransitionState; +import com.android.wm.shell.sysui.ShellController; import org.junit.Before; import org.junit.Test; @@ -73,6 +75,7 @@ import java.util.Set; public class PipControllerTest extends ShellTestCase { private PipController mPipController; + @Mock private ShellController mMockShellController; @Mock private DisplayController mMockDisplayController; @Mock private PhonePipMenuController mMockPhonePipMenuController; @Mock private PipAppOpsListener mMockPipAppOpsListener; @@ -102,7 +105,7 @@ public class PipControllerTest extends ShellTestCase { ((Runnable) invocation.getArgument(0)).run(); return null; }).when(mMockExecutor).execute(any()); - mPipController = new PipController(mContext, mMockDisplayController, + mPipController = new PipController(mContext, mMockShellController, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm, mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController, @@ -115,6 +118,11 @@ public class PipControllerTest extends ShellTestCase { } @Test + public void instantiatePipController_registerConfigChangeListener() { + verify(mMockShellController, times(1)).addConfigurationChangeListener(any()); + } + + @Test public void instantiatePipController_registersPipTransitionCallback() { verify(mMockPipTransitionController).registerPipTransitionCallback(any()); } @@ -136,7 +144,7 @@ public class PipControllerTest extends ShellTestCase { when(mockPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false); when(spyContext.getPackageManager()).thenReturn(mockPackageManager); - assertNull(PipController.create(spyContext, mMockDisplayController, + assertNull(PipController.create(spyContext, mMockShellController, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm, mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java index c90a8259a9ef..c10e4a143076 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java @@ -24,6 +24,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -90,12 +91,13 @@ public class SplitScreenControllerTests extends ShellTestCase { @Test public void testIsLaunchingAdjacently_notInSplitScreen() { doReturn(false).when(mSplitScreenController).isSplitScreenVisible(); + doReturn(true).when(mSplitScreenController).isValidToEnterSplitScreen(any()); // Verify launching the same activity returns true. Intent startIntent = createStartIntent("startActivity"); ActivityManager.RunningTaskInfo focusTaskInfo = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent); - mSplitScreenController.onFocusTaskChanged(focusTaskInfo); + doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo(); assertTrue(mSplitScreenController.isLaunchingAdjacently( startIntent, SPLIT_POSITION_TOP_OR_LEFT)); @@ -103,7 +105,7 @@ public class SplitScreenControllerTests extends ShellTestCase { Intent diffIntent = createStartIntent("diffActivity"); focusTaskInfo = createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, diffIntent); - mSplitScreenController.onFocusTaskChanged(focusTaskInfo); + doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo(); assertFalse(mSplitScreenController.isLaunchingAdjacently( startIntent, SPLIT_POSITION_TOP_OR_LEFT)); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java index af2c495c85c5..4b68870d4129 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java @@ -127,6 +127,9 @@ public class StageCoordinatorTests extends ShellTestCase { mRootTask = new TestRunningTaskInfoBuilder().build(); mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build(); mStageCoordinator.onTaskAppeared(mRootTask, mRootLeash); + + mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build(); + mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build(); } @Test @@ -224,8 +227,8 @@ public class StageCoordinatorTests extends ShellTestCase { mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME); verify(mMainStage).reorderChild(eq(testTaskId), eq(true), any(WindowContainerTransaction.class)); - verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false)); - verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(true)); + verify(mSideStage).dismiss(any(WindowContainerTransaction.class), eq(false)); + verify(mMainStage).resetBounds(any(WindowContainerTransaction.class)); } @Test @@ -237,8 +240,8 @@ public class StageCoordinatorTests extends ShellTestCase { mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME); verify(mSideStage).reorderChild(eq(testTaskId), eq(true), any(WindowContainerTransaction.class)); - verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(true)); - verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false)); + verify(mSideStage).resetBounds(any(WindowContainerTransaction.class)); + verify(mMainStage).dismiss(any(WindowContainerTransaction.class), eq(false)); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java new file mode 100644 index 000000000000..6cc3ae8001e4 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.sysui; + +import static org.junit.Assert.assertTrue; + +import android.content.res.Configuration; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.wm.shell.ShellTestCase; +import com.android.wm.shell.common.ShellExecutor; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Locale; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class ShellControllerTest extends ShellTestCase { + + @Mock + private ShellExecutor mExecutor; + + private ShellController mController; + private TestConfigurationChangeListener mListener; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mListener = new TestConfigurationChangeListener(); + mController = new ShellController(mExecutor); + mController.onConfigurationChanged(getConfigurationCopy()); + } + + @After + public void tearDown() { + // Do nothing + } + + @Test + public void testAddConfigurationChangeListener_ensureCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.densityDpi = 200; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + } + + @Test + public void testDoubleAddConfigurationChangeListener_ensureSingleCallback() { + mController.addConfigurationChangeListener(mListener); + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.densityDpi = 200; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + } + + @Test + public void testAddRemoveConfigurationChangeListener_ensureNoCallback() { + mController.addConfigurationChangeListener(mListener); + mController.removeConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.densityDpi = 200; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 0); + } + + @Test + public void testMultipleConfigurationChangeListeners() { + TestConfigurationChangeListener listener2 = new TestConfigurationChangeListener(); + mController.addConfigurationChangeListener(mListener); + mController.addConfigurationChangeListener(listener2); + + Configuration newConfig = getConfigurationCopy(); + newConfig.densityDpi = 200; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(listener2.configChanges == 1); + } + + @Test + public void testRemoveListenerDuringCallback() { + TestConfigurationChangeListener badListener = new TestConfigurationChangeListener() { + @Override + public void onConfigurationChanged(Configuration newConfiguration) { + mController.removeConfigurationChangeListener(this); + } + }; + mController.addConfigurationChangeListener(badListener); + mController.addConfigurationChangeListener(mListener); + + // Ensure we don't fail just because a listener was removed mid-callback + Configuration newConfig = getConfigurationCopy(); + newConfig.densityDpi = 200; + mController.onConfigurationChanged(newConfig); + } + + @Test + public void testDensityChangeCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.densityDpi = 200; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(mListener.densityChanges == 1); + assertTrue(mListener.smallestWidthChanges == 0); + assertTrue(mListener.themeChanges == 0); + assertTrue(mListener.localeChanges == 0); + } + + @Test + public void testFontScaleChangeCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.fontScale = 2; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(mListener.densityChanges == 1); + assertTrue(mListener.smallestWidthChanges == 0); + assertTrue(mListener.themeChanges == 0); + assertTrue(mListener.localeChanges == 0); + } + + @Test + public void testSmallestWidthChangeCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.smallestScreenWidthDp = 100; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(mListener.densityChanges == 0); + assertTrue(mListener.smallestWidthChanges == 1); + assertTrue(mListener.themeChanges == 0); + assertTrue(mListener.localeChanges == 0); + } + + @Test + public void testThemeChangeCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.assetsSeq++; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(mListener.densityChanges == 0); + assertTrue(mListener.smallestWidthChanges == 0); + assertTrue(mListener.themeChanges == 1); + assertTrue(mListener.localeChanges == 0); + } + + @Test + public void testNightModeChangeCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + newConfig.uiMode = Configuration.UI_MODE_NIGHT_YES; + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(mListener.densityChanges == 0); + assertTrue(mListener.smallestWidthChanges == 0); + assertTrue(mListener.themeChanges == 1); + assertTrue(mListener.localeChanges == 0); + } + + @Test + public void testLocaleChangeCallback() { + mController.addConfigurationChangeListener(mListener); + + Configuration newConfig = getConfigurationCopy(); + // Just change the locales to be different + if (newConfig.locale == Locale.CANADA) { + newConfig.locale = Locale.US; + } else { + newConfig.locale = Locale.CANADA; + } + mController.onConfigurationChanged(newConfig); + assertTrue(mListener.configChanges == 1); + assertTrue(mListener.densityChanges == 0); + assertTrue(mListener.smallestWidthChanges == 0); + assertTrue(mListener.themeChanges == 0); + assertTrue(mListener.localeChanges == 1); + } + + private Configuration getConfigurationCopy() { + final Configuration c = new Configuration(InstrumentationRegistry.getInstrumentation() + .getTargetContext().getResources().getConfiguration()); + // In tests this might be undefined so make sure it's valid + c.assetsSeq = 1; + return c; + } + + private class TestConfigurationChangeListener implements ConfigurationChangeListener { + // Counts of number of times each of the callbacks are called + public int configChanges; + public int densityChanges; + public int smallestWidthChanges; + public int themeChanges; + public int localeChanges; + + @Override + public void onConfigurationChanged(Configuration newConfiguration) { + configChanges++; + } + + @Override + public void onDensityOrFontScaleChanged() { + densityChanges++; + } + + @Override + public void onSmallestScreenWidthChanged() { + smallestWidthChanges++; + } + + @Override + public void onThemeChanged() { + themeChanges++; + } + + @Override + public void onLocaleOrLayoutDirectionChanged() { + localeChanges++; + } + } +} diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING index 4ec4767a35cc..05fbc7a52ec6 100644 --- a/media/TEST_MAPPING +++ b/media/TEST_MAPPING @@ -22,11 +22,15 @@ } ], "file_patterns": ["(?i)drm|crypto"] - } - ], - "imports": [ + }, { - "path": "frameworks/av/drm/mediadrm/plugins" + "name": "CtsMediaDrmFrameworkTestCases", + "options" : [ + { + "include-annotation": "android.platform.test.annotations.Presubmit" + } + ], + "file_patterns": ["(?i)drm|crypto"] } ] } diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml index 480bc484b73a..004b5632a18b 100644 --- a/packages/CompanionDeviceManager/res/values-af/strings.xml +++ b/packages/CompanionDeviceManager/res/values-af/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string> <string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string> diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml index 5f2bd7f1b3f9..b1f414414a15 100644 --- a/packages/CompanionDeviceManager/res/values-am/strings.xml +++ b/packages/CompanionDeviceManager/res/values-am/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን ስልክ ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string> diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml index 138386b0b8e6..4268c0b909ee 100644 --- a/packages/CompanionDeviceManager/res/values-ar/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"بث تطبيقات هاتفك"</string> <string name="title_app_streaming" msgid="2270331024626446950">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"تطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"يطلب التطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> لمشاركة التطبيقات بين أجهزتك."</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"السماح"</string> diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml index 95c4e68c0dcf..644140035398 100644 --- a/packages/CompanionDeviceManager/res/values-as/strings.xml +++ b/packages/CompanionDeviceManager/res/values-as/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"আপোনাৰ ফ’নৰ এপ্ ষ্ট্ৰীম কৰক"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ফ’নৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুৰোধ জনাইছে"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string> diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml index 9578fb5fcf47..3549317b383f 100644 --- a/packages/CompanionDeviceManager/res/values-az/strings.xml +++ b/packages/CompanionDeviceManager/res/values-az/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun tətbiqlərini yayımlayın"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string> <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string> diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml index d82124758ce6..75a4f1d2aeeb 100644 --- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string> <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string> diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml index 2086f2eddf09..82ff9ae00138 100644 --- a/packages/CompanionDeviceManager/res/values-be/strings.xml +++ b/packages/CompanionDeviceManager/res/values-be/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Трансліруйце змесціва праграм з вашага тэлефона"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў вашага тэлефона"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на перадачу праграм плынню паміж вашымі прыладамі"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string> diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml index 134ae1c90bab..0154bfb7aac7 100644 --- a/packages/CompanionDeviceManager/res/values-bg/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Поточно предаване на приложенията на телефона ви"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string> diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml index 08c4a16b9000..abdc12847bd3 100644 --- a/packages/CompanionDeviceManager/res/values-bn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"আপনার ফোনের অ্যাপ স্ট্রিমিংয়ের মাধ্যমে কাস্ট করুন"</string> <string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string> diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml index 340fd6a1e532..d7423ac9ceee 100644 --- a/packages/CompanionDeviceManager/res/values-bs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama s telefona"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa ovim informacijama s vašeg telefona"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string> <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string> diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml index 967b390c36a5..a40efd019477 100644 --- a/packages/CompanionDeviceManager/res/values-ca/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Reprodueix en continu aplicacions del telèfon"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per reproduir en continu aplicacions entre els dispositius"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permet"</string> diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml index 7ab5f6243b11..cfea6c388351 100644 --- a/packages/CompanionDeviceManager/res/values-cs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Povolit"</string> diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml index 2fb2e6e4d81c..5ba30ec39c51 100644 --- a/packages/CompanionDeviceManager/res/values-da/strings.xml +++ b/packages/CompanionDeviceManager/res/values-da/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Giv <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adgang til disse oplysninger fra din telefon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Tillad, at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> får adgang til disse oplysninger fra din telefon"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string> <string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Tillad"</string> diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml index 0b6a195763c6..21f0322ce873 100644 --- a/packages/CompanionDeviceManager/res/values-de/strings.xml +++ b/packages/CompanionDeviceManager/res/values-de/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Smartphone-Apps streamen"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string> diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml index 726009fb0638..2c27f9281e4c 100644 --- a/packages/CompanionDeviceManager/res/values-el/strings.xml +++ b/packages/CompanionDeviceManager/res/values-el/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string> <string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml index dacfaaeee4a3..982101456424 100644 --- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Allow"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml index dacfaaeee4a3..982101456424 100644 --- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Allow"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml index dacfaaeee4a3..982101456424 100644 --- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Allow"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml index dacfaaeee4a3..982101456424 100644 --- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Allow"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml index 56d979a7b950..ea1ff66c672d 100644 --- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media, and notifications"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media, and notifications"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Allow"</string> diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml index 54d13c4a42a9..143e1cb32178 100644 --- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Transmitir las apps de tu teléfono"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string> diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml index 0d0b10e7ce4a..6edc02ae647e 100644 --- a/packages/CompanionDeviceManager/res/values-es/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Emite las aplicaciones de tu teléfono"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde tu teléfono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde tu teléfono"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string> diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml index b1603903cfc7..d15b975bac89 100644 --- a/packages/CompanionDeviceManager/res/values-et/strings.xml +++ b/packages/CompanionDeviceManager/res/values-et/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotlevad teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"seade"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Luba"</string> diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml index 395c385948da..fda2c4e3c4b6 100644 --- a/packages/CompanionDeviceManager/res/values-eu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko aplikazioak"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Eman informazio hori telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string> diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml index beabaf1842bd..0edab4d03d5f 100644 --- a/packages/CompanionDeviceManager/res/values-fa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"جاریسازی برنامههای تلفن"</string> <string name="title_app_streaming" msgid="2270331024626446950">"اجازه دادن به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> برای دسترسی به اطلاعات تلفن"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویسهای بیندستگاهی"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> به عکسها، رسانه، و اعلانهای تلفن شما دسترسی پیدا کند"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> مجاز میشود به این اطلاعات در دستگاهتان دسترسی پیدا کند"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"عکسها و رسانهها"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامهها را بین دستگاههای شما جاریسازی کند"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string> diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml index 35e0e47a0649..b34bb364df0c 100644 --- a/packages/CompanionDeviceManager/res/values-fi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Striimaa puhelimen sovelluksia"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa pääsyn näihin puhelimesi tietoihin"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa striimata sovelluksia laitteidesi välillä"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"laite"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Salli"</string> diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml index 1b1727e8bc10..7e46c468d0b2 100644 --- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Diffusez les applications de votre téléphone"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string> diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml index 30db3187857e..b8cd4995bf5a 100644 --- a/packages/CompanionDeviceManager/res/values-fr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Diffuser en streaming les applis de votre téléphone"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string> diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml index c692c034cf22..ae9111ebbcba 100644 --- a/packages/CompanionDeviceManager/res/values-gl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde o teu teléfono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde o teu teléfono"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir aplicacións entre os teus aparellos"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string> diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml index 8c92de8b96e0..747b331dd30d 100644 --- a/packages/CompanionDeviceManager/res/values-gu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"તમારા ફોનની ઍપ સ્ટ્રીમ કરો"</string> <string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ફોનના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string> diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml index 1ac399946cbe..8f06cc21ae49 100644 --- a/packages/CompanionDeviceManager/res/values-hi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"अपने फ़ोन के ऐप्लिकेशन को स्ट्रीम करें"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रही हैं"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवाएं"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, डिवाइसों के बीच ऐप्लिकेशन को स्ट्रीम करने की अनुमति मांग रहा है"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string> diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml index 6e186281e3b6..7f8a5893ab8e 100644 --- a/packages/CompanionDeviceManager/res/values-hr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikacija vašeg telefona"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> da pristupi fotografijama, medijskim sadržajima i obavijestima na telefonu"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za emitiranje aplikacija između vaših uređaja"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za streamanje aplikacija između vaših uređaja"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string> <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string> diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml index 2f8dd8536844..389a8213dcbd 100644 --- a/packages/CompanionDeviceManager/res/values-hu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"A telefon alkalmazásainak streamelése"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string> diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml index aed650b7c472..96a6fe28d74f 100644 --- a/packages/CompanionDeviceManager/res/values-hy/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Հեռարձակել հեռախոսի հավելվածները"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string> diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml index 048325c4f676..a5fa8011cc87 100644 --- a/packages/CompanionDeviceManager/res/values-in/strings.xml +++ b/packages/CompanionDeviceManager/res/values-in/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikasi ponsel"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses informasi ini dari ponsel Anda"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses informasi ini dari ponsel Anda"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string> diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml index 3f5a3de9de77..7313cda259c0 100644 --- a/packages/CompanionDeviceManager/res/values-is/strings.xml +++ b/packages/CompanionDeviceManager/res/values-is/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Streymdu forritum símans"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild fyrir straumspilun forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string> diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml index 0f7fb08c9da3..5ea7c0a43246 100644 --- a/packages/CompanionDeviceManager/res/values-it/strings.xml +++ b/packages/CompanionDeviceManager/res/values-it/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Trasmetti in streaming le app del tuo telefono"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Consenti a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a queste informazioni dal tuo telefono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Consenti a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a questa informazione dal tuo telefono"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Consenti"</string> diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml index 9622ce54aa6a..d488e2865063 100644 --- a/packages/CompanionDeviceManager/res/values-iw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"שידור אפליקציות מהטלפון"</string> <string name="title_app_streaming" msgid="2270331024626446950">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string> <string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string> diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml index 97bc56d629c0..041a5a4e1968 100644 --- a/packages/CompanionDeviceManager/res/values-ja/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml @@ -16,7 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャ"</string> + <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャー"</string> <string name="confirmation_title" msgid="3785000297483688997">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> へのアクセスを許可"</string> <string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string> <string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string> @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"スマートフォンのアプリのストリーミング"</string> <string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"このスマートフォンからの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"許可"</string> diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml index 94c33e5df268..6fa113fcb21e 100644 --- a/packages/CompanionDeviceManager/res/values-ka/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"თქვენი ტელეფონის აპების სტრიმინგი"</string> <string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის სტრიმინგი შეძლოს"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string> diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml index 5a4314bf9979..0625210ed3cc 100644 --- a/packages/CompanionDeviceManager/res/values-kk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Телефон қолданбаларын трансляциялайды."</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string> diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml index 2456f63f1b34..854fcac990ec 100644 --- a/packages/CompanionDeviceManager/res/values-km/strings.xml +++ b/packages/CompanionDeviceManager/res/values-km/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"ផ្សាយកម្មវិធីរបស់ទូរសព្ទអ្នក"</string> <string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string> diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml index 5284ebf93c6c..809a811e1ba4 100644 --- a/packages/CompanionDeviceManager/res/values-kn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"ನಿಮ್ಮ ಫೋನ್ನ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ನಿಮ್ಮ ಫೋನ್ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string> diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml index 4451cb93456c..79cd1b6f6330 100644 --- a/packages/CompanionDeviceManager/res/values-ko/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"휴대전화의 앱을 스트리밍합니다."</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"기기"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"허용"</string> diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml index d641f299d652..634804392f42 100644 --- a/packages/CompanionDeviceManager/res/values-ky/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Телефондогу колдонмолорду алып ойнотуу"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиа"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду тышкы экранга чыгарууга уруксат сурап жатат"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Ооба"</string> diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml index f9d65faee9a2..47fbadd1dba7 100644 --- a/packages/CompanionDeviceManager/res/values-lo/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຂອງໂທລະສັບທ່ານ"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string> diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml index 6e7b00786221..cc377793a3e3 100644 --- a/packages/CompanionDeviceManager/res/values-lt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Telefono programų perdavimas srautu"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Leisti"</string> diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml index 1fdc99d82be8..f1c6f8dbbc24 100644 --- a/packages/CompanionDeviceManager/res/values-lv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Var straumēt jūsu tālruņa lietotnes"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string> diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml index e09a5b395efa..46fcc02e0c8c 100644 --- a/packages/CompanionDeviceManager/res/values-mk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Стримувајте ги апликациите на телефонот"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Овозможете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Овозможете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"уред"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string> diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml index 636a7507940e..27682d4c1af1 100644 --- a/packages/CompanionDeviceManager/res/values-ml/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"നിങ്ങളുടെ ഫോണിലെ ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string> diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml index 64b284dcb6cb..84a986fba631 100644 --- a/packages/CompanionDeviceManager/res/values-mn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Таны утасны аппуудыг дамжуулах"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс утасны зураг, медиа болон мэдэгдэлд хандахын тулд зөвшөөрөл хүсэж байна"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс төхөөрөмж хооронд апп дамжуулахын тулд зөвшөөрөл хүсэж байна"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string> <string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string> diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml index a070e6199469..24e92e56e316 100644 --- a/packages/CompanionDeviceManager/res/values-mr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"फोनवरील ॲप्स स्ट्रीम करा"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string> diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml index e6932e13beaa..037d4de3f253 100644 --- a/packages/CompanionDeviceManager/res/values-ms/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Strim apl telefon anda"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses maklumat ini daripada telefon anda"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses maklumat ini daripada telefon anda"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string> diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml index 778f7be59870..1362ddfeee82 100644 --- a/packages/CompanionDeviceManager/res/values-my/strings.xml +++ b/packages/CompanionDeviceManager/res/values-my/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အား သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုခြင်း"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string> <string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string> diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml index 274b1a9b5e8c..1b269254e638 100644 --- a/packages/CompanionDeviceManager/res/values-nb/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Strøm appene på telefonen"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å få tilgang til bilder, medier og varsler på telefonen din"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å strømme apper mellom enhetene dine"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Tillat"</string> diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml index ac3338e2c211..95028eb14d79 100644 --- a/packages/CompanionDeviceManager/res/values-ne/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string> diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml index 3eb49c556a29..31b590357d1b 100644 --- a/packages/CompanionDeviceManager/res/values-nl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"De apps van je telefoon streamen"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string> <string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string> diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml index b9c543436e7e..1d63ec381fc4 100644 --- a/packages/CompanionDeviceManager/res/values-or/strings.xml +++ b/packages/CompanionDeviceManager/res/values-or/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string> diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml index 3d35e55ed68c..07989f715a84 100644 --- a/packages/CompanionDeviceManager/res/values-pa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string> diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml index 08f6880afa9c..3ccbed7b3175 100644 --- a/packages/CompanionDeviceManager/res/values-pl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Odtwarzaj strumieniowo aplikacje z telefonu"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Zezwól aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania aplikacji między urządzeniami"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml index ce83bff93d0d..5c426048c824 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml index 8d84eb76dded..1ed65bd88d11 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Faça stream das apps do telemóvel"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, conteúdo multimédia e notificações do seu telemóvel"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml index ce83bff93d0d..5c426048c824 100644 --- a/packages/CompanionDeviceManager/res/values-pt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string> diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml index b6f8ff7a89b7..276ebfdda3c7 100644 --- a/packages/CompanionDeviceManager/res/values-ro/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Să redea în stream aplicațiile telefonului"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Permiteți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Permiteți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string> <string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string> diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml index 492e345b93fd..d5031bd2d5f3 100644 --- a/packages/CompanionDeviceManager/res/values-ru/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Трансляция приложений с телефона."</string> <string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает доступ от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string> diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml index 79c36513a575..b2451e9ef41b 100644 --- a/packages/CompanionDeviceManager/res/values-si/strings.xml +++ b/packages/CompanionDeviceManager/res/values-si/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"ඔබගේ දුරකථනයේ යෙදුම් ප්රවාහ කරන්න"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්ය සහ දැනුම්දීම් වෙත ප්රවේශ වීමට අවසරය ඉල්ලමින් සිටී"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්ය"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්රවාහ කිරීමට අවසරය ඉල්ලමින් සිටී"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්ය සහ දැනුම්දීම් වෙත ප්රවේශ වීමට අවසරය ඉල්ලමින් සිටියි"</string> <string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string> diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml index 54b6ce6d66ad..787c1854d3e8 100644 --- a/packages/CompanionDeviceManager/res/values-sk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Streamovanie aplikácií v telefóne"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string> <string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string> diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml index 883bd0bcdb95..42453bab1d22 100644 --- a/packages/CompanionDeviceManager/res/values-sl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string> diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml index 3e6933ccb8db..2550f71fd665 100644 --- a/packages/CompanionDeviceManager/res/values-sq/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Lejo"</string> diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml index f9a1e0248aaa..354ff2c2ac13 100644 --- a/packages/CompanionDeviceManager/res/values-sr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string> <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string> diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml index b4df61613e9c..99df831a8942 100644 --- a/packages/CompanionDeviceManager/res/values-sv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Streama telefonens appar"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string> diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml index 6b5ca21a69de..2618de765c2f 100644 --- a/packages/CompanionDeviceManager/res/values-sw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Tiririsha programu za simu yako"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kufikia picha, maudhui na arifa za simu yako"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kutiririsha programu kati ya vifaa vyako"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string> diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml index 4408e65d8e81..8a32deea6a6b 100644 --- a/packages/CompanionDeviceManager/res/values-ta/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"உங்கள் மொபைலின் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string> <string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவும்"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"உங்கள் மொபைலிலிருந்து இந்தத் தகவலை அணுக <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதியுங்கள்"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string> diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml index 7bb383fc5f9c..446d91b9b020 100644 --- a/packages/CompanionDeviceManager/res/values-te/strings.xml +++ b/packages/CompanionDeviceManager/res/values-te/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"మీ ఫోన్ యాప్లను స్ట్రీమ్ చేయండి"</string> <string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> మీ ఫోన్ ఫోటోలు, మీడియా, నోటిఫికేషన్లను యాక్సెస్ చేయడానికి మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరపున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string> @@ -35,10 +36,11 @@ <string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"మీ పరికరాల మధ్య యాప్లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరపున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string> <string name="summary_generic" msgid="2346762210105903720"></string> - <string name="consent_yes" msgid="8344487259618762872">"అనుమతించు"</string> + <string name="consent_yes" msgid="8344487259618762872">"అనుమతించండి"</string> <string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string> <string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string> <string name="permission_sync_confirmation_title" msgid="667074294393493186">"మీ వాచ్కు యాప్ అనుమతులను బదిలీ చేయండి"</string> diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml index e3174f8c9012..a75888269d53 100644 --- a/packages/CompanionDeviceManager/res/values-th/strings.xml +++ b/packages/CompanionDeviceManager/res/values-th/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"สตรีมแอปของโทรศัพท์คุณ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนในโทรศัพท์ของคุณ"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string> diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml index 9c49c5c78df7..d7e9ab69d9f8 100644 --- a/packages/CompanionDeviceManager/res/values-tl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"I-stream ang mga app ng iyong telepono"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyong ito sa iyong telepono"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyon sa iyong telepono"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string> <string name="profile_name_generic" msgid="6851028682723034988">"device"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Payagan"</string> diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml index bdad64149415..826d48657e4e 100644 --- a/packages/CompanionDeviceManager/res/values-tr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını yayınlama"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string> diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml index 760255b4b64a..89cd2c33a609 100644 --- a/packages/CompanionDeviceManager/res/values-uk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Транслювати додатки телефона"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Надайте пристрою <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string> diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml index a311bd4936a8..7f183b8894bd 100644 --- a/packages/CompanionDeviceManager/res/values-ur/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"اپنے فون کی ایپس کی سلسلہ بندی کریں"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی اجازت دیں"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت طلب کر رہی ہے"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"اپنے فون سے اس معلومات تک رسائی حاصل Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کرنے کی اجازت دیں"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play سروسز"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string> diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml index f1c162afa666..17426067fabf 100644 --- a/packages/CompanionDeviceManager/res/values-uz/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Telefondagi ilovalarni translatsiya qilish"</string> <string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string> diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml index 5c7d600a83e6..43066140eeb8 100644 --- a/packages/CompanionDeviceManager/res/values-vi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml @@ -25,7 +25,7 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Truyền các ứng dụng trên điện thoại của bạn"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string> + <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string> @@ -35,7 +35,7 @@ <string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string> + <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string> <string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string> diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml index 5a1017f72668..2df8b4ff3d43 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"流式传输手机上的应用"</string> <string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”<strong></strong>访问您手机中的这项信息"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 访问您手机中的这项信息"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"设备"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"允许"</string> diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml index 4748ece86a5a..7c2541b2a211 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"串流播放手機應用程式內容"</string> <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便存取手機上的相片、媒體和通知"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便在裝置之間串流應用程式內容"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"允許"</string> diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml index f41896fd602f..9dd391900a8b 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"串流傳輸手機應用程式內容"</string> <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取手機中的這項資訊"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便存取手機上的相片、媒體和通知"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取你手機中的這項資訊"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"允許"</string> diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml index 87ed7e6e8adf..5fed63928a59 100644 --- a/packages/CompanionDeviceManager/res/values-zu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml @@ -25,7 +25,8 @@ <string name="permission_apps_summary" msgid="798718816711515431">"Sakaza ama-app wefoni yakho"</string> <string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifinyelele lolu lwazi kusukela efonini yakho"</string> <string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string> - <string name="helper_summary_app_streaming" msgid="7380294597268573523">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string> + <!-- no translation found for helper_summary_app_streaming (5977509499890099) --> + <skip /> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> <string name="title_computer" msgid="4693714143506569253">"Vumela <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukufinyelela lolu lwazi kusuka efonini yakho"</string> @@ -35,7 +36,8 @@ <string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string> <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string> - <string name="helper_summary_computer" msgid="1676407599909474428">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string> + <!-- no translation found for helper_summary_computer (9050724687678157852) --> + <skip /> <string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string> <string name="summary_generic" msgid="2346762210105903720"></string> <string name="consent_yes" msgid="8344487259618762872">"Vumela"</string> diff --git a/packages/DynamicSystemInstallationService/res/values-or/strings.xml b/packages/DynamicSystemInstallationService/res/values-or/strings.xml index 05b9016d45b0..b5ec29259f7c 100644 --- a/packages/DynamicSystemInstallationService/res/values-or/strings.xml +++ b/packages/DynamicSystemInstallationService/res/values-or/strings.xml @@ -7,7 +7,7 @@ <string name="notification_install_failed" msgid="4066039210317521404">"ଇନଷ୍ଟଲ୍ କରିବା ବିଫଳ ହୋଇଛି"</string> <string name="notification_image_validation_failed" msgid="2720357826403917016">"ଇମେଜ୍ ବୈଧକରଣ ବିଫଳ ହୋଇଛି। ଇନଷ୍ଟଲେସନ୍ ରଦ୍ଦ କରନ୍ତୁ।"</string> <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ବର୍ତ୍ତମାନ ଏକ ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଚାଲୁଛି। ମୂଳ Android ସଂସ୍କରଣ ବ୍ୟବହାର କରିବାକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string> - <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ କରନ୍ତୁ"</string> <string name="notification_action_discard" msgid="1817481003134947493">"ଖାରଜ କରନ୍ତୁ"</string> <string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string> <string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string> diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml index fac338bca0a8..fe6edcea8dd8 100644 --- a/packages/PackageInstaller/res/values-eu/strings.xml +++ b/packages/PackageInstaller/res/values-eu/strings.xml @@ -85,8 +85,8 @@ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan. Hori aldatzeko, joan Ezarpenak atalera."</string> <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan. Hori aldatzeko, joan Ezarpenak atalera."</string> <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Baliteke telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea."</string> - <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> - <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string> + <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Baliteke tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu hura erabiltzeagatik tabletari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea zeu izango zarela."</string> + <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Baliteke telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu hura erabiltzeagatik telebistari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea zeu izango zarela."</string> <string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string> <string name="external_sources_settings" msgid="4046964413071713807">"Ezarpenak"</string> <string name="wear_app_channel" msgid="1960809674709107850">"Wear aplikazioak instalatzea/desinstalatzea"</string> diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml index 4bc5bec46543..75d5d2ddb1ce 100644 --- a/packages/PackageInstaller/res/values-or/strings.xml +++ b/packages/PackageInstaller/res/values-or/strings.xml @@ -20,7 +20,7 @@ <string name="install" msgid="711829760615509273">"ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string> <string name="update" msgid="3932142540719227615">"ଅପଡେଟ୍ କରନ୍ତୁ"</string> <string name="done" msgid="6632441120016885253">"ହୋଇଗଲା"</string> - <string name="cancel" msgid="1018267193425558088">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="cancel" msgid="1018267193425558088">"ବାତିଲ କରନ୍ତୁ"</string> <string name="installing" msgid="4921993079741206516">"ଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string> <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string> <string name="install_done" msgid="5987363587661783896">"ଆପ ଇନଷ୍ଟଲ ହୋଇଗଲା।"</string> diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml index fa10909b92ed..6f215d3af18b 100644 --- a/packages/PrintSpooler/res/values-or/strings.xml +++ b/packages/PrintSpooler/res/values-or/strings.xml @@ -83,7 +83,7 @@ <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ବାତିଲ୍ କରାଯାଉଛି"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ପ୍ରିଣ୍ଟର୍ ତ୍ରୁଟି"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"ପ୍ରିଣ୍ଟର୍ ଦ୍ୱାରା ରୋକାଯାଇଥିବା <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> - <string name="cancel" msgid="4373674107267141885">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="cancel" msgid="4373674107267141885">"ବାତିଲ କରନ୍ତୁ"</string> <string name="restart" msgid="2472034227037808749">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string> <string name="no_connection_to_printer" msgid="2159246915977282728">"ପ୍ରିଣ୍ଟର୍କୁ କୌଣସି ସଂଯୋଗ ନାହିଁ"</string> <string name="reason_unknown" msgid="5507940196503246139">"ଅଜଣା"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 7f1e6f80b868..a52e71899599 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -667,7 +667,7 @@ <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ነባሪ"</string> <string name="turn_screen_on_title" msgid="3266937298097573424">"ማያ ገጽን ያብሩ"</string> <string name="allow_turn_screen_on" msgid="6194845766392742639">"ማያ ገጹን ማብራት ይፍቀዱ"</string> - <string name="allow_turn_screen_on_description" msgid="43834403291575164">"አንድ መተግበሪያ ማያ ገጹን እንዲያበራ ይፍቀዱለት። ከተሰጠ፣ መተግበሪያው ያለእርስዎ ግልጽ ሐሳብ በማንኛውም ጊዜ ማያ ገጹን ሊያበራ ይችላል።"</string> + <string name="allow_turn_screen_on_description" msgid="43834403291575164">"አንድ መተግበሪያ ማያ ገጹን እንዲያበራ ይፍቀዱለት። ከተሰጠ፣ መተግበሪያው ያለእርስዎ ግልፅ ሐሳብ በማንኛውም ጊዜ ማያ ገጹን ሊያበራ ይችላል።"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index d383919a9d73..8f6de31ac409 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -665,7 +665,7 @@ <string name="physical_keyboard_title" msgid="4811935435315835220">"Fyysinen näppäimistö"</string> <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Valitse näppäimistöasettelu"</string> <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Oletus"</string> - <string name="turn_screen_on_title" msgid="3266937298097573424">"Käynnistä näyttö"</string> + <string name="turn_screen_on_title" msgid="3266937298097573424">"Näytön käynnistys"</string> <string name="allow_turn_screen_on" msgid="6194845766392742639">"Salli näytön käynnistäminen"</string> <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Salli sovelluksen käynnistää näyttö. Jos sovellus saa luvan, se voi käynnistää näytön itsenäisesti milloin tahansa."</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index e25124c953b1..db496bac51fe 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -148,7 +148,7 @@ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"ପେୟାର୍"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ପେୟାର୍"</string> - <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ବାତିଲ କରନ୍ତୁ"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ପେୟାରିଂ ଫଳରେ ସଂଯୁକ୍ତ ଥିବା ବେଳେ ଆପଣଙ୍କ ସମ୍ପର୍କଗୁଡ଼ିକୁ ଏବଂ କଲ୍ର ଇତିବୃତିକୁ ଆକସେସ୍ ମଞ୍ଜୁର ହୁଏ।"</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍ କରିହେଲା ନାହିଁ।"</string> <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ଏକ ଭୁଲ୍ PIN କିମ୍ବା ପାସକୀ କାରଣରୁ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍ କରିପାରିଲା ନାହିଁ।"</string> @@ -305,7 +305,7 @@ <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ବ୍ୟକ୍ତିଗତ DNS"</string> <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍ ବାଛନ୍ତୁ"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"ବନ୍ଦ"</string> - <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ସ୍ଵଚାଳିତ"</string> + <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ଅଟୋମେଟିକ"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"ବ୍ୟକ୍ତିଗତ DNS ପ୍ରଦାତା ହୋଷ୍ଟନାମ"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ପ୍ରଦାନକାରୀଙ୍କ ହୋଷ୍ଟନାମ ଲେଖନ୍ତୁ"</string> <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string> @@ -524,7 +524,7 @@ <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}=1{1ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}other{#ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}}"</string> <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ଅଧିକ ସମୟ।"</string> <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"କମ୍ ସମୟ।"</string> - <string name="cancel" msgid="5665114069455378395">"ବାତିଲ୍"</string> + <string name="cancel" msgid="5665114069455378395">"ବାତିଲ"</string> <string name="okay" msgid="949938843324579502">"ଠିକ୍ ଅଛି"</string> <string name="done" msgid="381184316122520313">"ହୋଇଗଲା"</string> <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string> @@ -624,7 +624,7 @@ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ଡିଭାଇସ୍ ଡିଫଲ୍ଟ"</string> <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ଅକ୍ଷମ କରାଯାଇଛି"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string> - <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ୍ କରନ୍ତୁ।"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ କରନ୍ତୁ।"</string> <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ତାରଯୁକ୍ତ ହେଡଫୋନ୍"</string> <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ଚାଲୁ ଅଛି"</string> <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"ବନ୍ଦ ଅଛି"</string> diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml index a5b9f79325fd..513fb6e87a10 100644 --- a/packages/SettingsLib/res/values-te/arrays.xml +++ b/packages/SettingsLib/res/values-te/arrays.xml @@ -50,8 +50,8 @@ </string-array> <string-array name="hdcp_checking_titles"> <item msgid="2377230797542526134">"ఎప్పటికీ తనిఖీ చేయవద్దు"</item> - <item msgid="3919638466823112484">"DRM కంటెంట్కు మాత్రమే తనిఖీ చేయండి"</item> - <item msgid="9048424957228926377">"ఎల్లప్పుడూ తనిఖీ చేయండి"</item> + <item msgid="3919638466823112484">"DRM కంటెంట్కు మాత్రమే చెక్ చేయండి"</item> + <item msgid="9048424957228926377">"ఎల్లప్పుడూ చెక్ చేయండి"</item> </string-array> <string-array name="hdcp_checking_summaries"> <item msgid="4045840870658484038">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించవద్దు"</item> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index bec67ec807ef..e9d3fd0e84ca 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -204,7 +204,7 @@ <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g>కి పూర్తి మద్దతు ఉంది"</string> <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g>కి నెట్వర్క్ కనెక్షన్ అవసరం"</string> <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g>కు మద్దతు లేదు"</string> - <string name="tts_status_checking" msgid="8026559918948285013">"తనిఖీ చేస్తోంది..."</string> + <string name="tts_status_checking" msgid="8026559918948285013">"చెక్ చేస్తోంది..."</string> <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> కోసం సెట్టింగ్లు"</string> <string name="tts_engine_settings_button" msgid="477155276199968948">"ఇంజిన్ సెట్టింగ్లను ప్రారంభించండి"</string> <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"ప్రాధాన్య ఇంజిన్"</string> @@ -336,7 +336,7 @@ <string name="dev_settings_warning_title" msgid="8251234890169074553">"అభివృద్ధి సెట్టింగ్లను అనుమతించాలా?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"ఈ సెట్టింగ్లు అభివృద్ధి వినియోగం కోసం మాత్రమే ఉద్దేశించబడినవి. వీటి వలన మీ పరికరం మరియు దీనిలోని యాప్లు విచ్ఛిన్నం కావచ్చు లేదా తప్పుగా ప్రవర్తించవచ్చు."</string> <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ద్వారా యాప్లను వెరిఫై చేయి"</string> - <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్స్టాల్ చేయబడిన యాప్లను తనిఖీ చేయి."</string> + <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్స్టాల్ చేయబడిన యాప్లను చెక్ చేయండి."</string> <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"పేర్లు (MAC అడ్రస్లు మాత్రమే) లేని బ్లూటూత్ పరికరాలు డిస్ప్లే కాబడతాయి"</string> <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"రిమోట్ పరికరాల్లో ఆమోదించలేని స్థాయిలో అధిక వాల్యూమ్ ఉండటం లేదా వాల్యూమ్ కంట్రోల్ లేకపోవడం వంటి సమస్యలు ఉంటే బ్లూటూత్ సంపూర్ణ వాల్యూమ్ ఫీచర్ను డిజేబుల్ చేస్తుంది."</string> <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"బ్లూటూత్ Gabeldorsche ఫీచర్ స్ట్యాక్ను ఎనేబుల్ చేస్తుంది."</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java index bf9debf5ccce..bf6975714acd 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java @@ -87,9 +87,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { if (DEBUG) { Log.d(TAG, "Bluetooth service connected"); } - mService = (BluetoothLeBroadcast) proxy; - mIsProfileReady = true; - registerServiceCallBack(mExecutor, mBroadcastCallback); + if(!mIsProfileReady) { + mService = (BluetoothLeBroadcast) proxy; + mIsProfileReady = true; + registerServiceCallBack(mExecutor, mBroadcastCallback); + } } @Override @@ -97,8 +99,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { if (DEBUG) { Log.d(TAG, "Bluetooth service disconnected"); } - mIsProfileReady = false; - unregisterServiceCallBack(mBroadcastCallback); + if(mIsProfileReady) { + mIsProfileReady = false; + unregisterServiceCallBack(mBroadcastCallback); + } } }; diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index d6d73046bed3..281501e6043c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.graphics.drawable.Drawable; +import android.media.AudioManager; import android.media.RoutingSessionInfo; import android.os.Build; import android.text.TextUtils; @@ -83,6 +84,7 @@ public class LocalMediaManager implements BluetoothCallback { private InfoMediaManager mInfoMediaManager; private String mPackageName; private MediaDevice mOnTransferBluetoothDevice; + private AudioManager mAudioManager; @VisibleForTesting List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); @@ -126,6 +128,7 @@ public class LocalMediaManager implements BluetoothCallback { mPackageName = packageName; mLocalBluetoothManager = LocalBluetoothManager.getInstance(context, /* onInitCallback= */ null); + mAudioManager = context.getSystemService(AudioManager.class); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mLocalBluetoothManager == null) { Log.e(TAG, "Bluetooth is not supported on this device"); @@ -148,6 +151,7 @@ public class LocalMediaManager implements BluetoothCallback { mInfoMediaManager = infoMediaManager; mPackageName = packageName; mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mAudioManager = context.getSystemService(AudioManager.class); } /** @@ -527,13 +531,16 @@ public class LocalMediaManager implements BluetoothCallback { synchronized (mMediaDevicesLock) { mMediaDevices.clear(); mMediaDevices.addAll(devices); - // Add disconnected bluetooth devices only when phone output device is available. + // Add muting expected bluetooth devices only when phone output device is available. for (MediaDevice device : devices) { final int type = device.getDeviceType(); if (type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE || type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE) { - mMediaDevices.addAll(buildDisconnectedBluetoothDevice()); + MediaDevice mutingExpectedDevice = getMutingExpectedDevice(); + if (mutingExpectedDevice != null) { + mMediaDevices.add(mutingExpectedDevice); + } break; } } @@ -552,6 +559,34 @@ public class LocalMediaManager implements BluetoothCallback { } } + private MediaDevice getMutingExpectedDevice() { + if (mBluetoothAdapter == null + || mAudioManager.getMutingExpectedDevice() == null) { + Log.w(TAG, "BluetoothAdapter is null or muting expected device not exist"); + return null; + } + final List<BluetoothDevice> bluetoothDevices = + mBluetoothAdapter.getMostRecentlyConnectedDevices(); + final CachedBluetoothDeviceManager cachedDeviceManager = + mLocalBluetoothManager.getCachedDeviceManager(); + for (BluetoothDevice device : bluetoothDevices) { + final CachedBluetoothDevice cachedDevice = + cachedDeviceManager.findDevice(device); + if (isBondedMediaDevice(cachedDevice) && isMutingExpectedDevice(cachedDevice)) { + return new BluetoothMediaDevice(mContext, + cachedDevice, + null, null, mPackageName); + } + } + return null; + } + + private boolean isMutingExpectedDevice(CachedBluetoothDevice cachedDevice) { + return mAudioManager.getMutingExpectedDevice() != null + && cachedDevice.getAddress().equals( + mAudioManager.getMutingExpectedDevice().getAddress()); + } + private List<MediaDevice> buildDisconnectedBluetoothDevice() { if (mBluetoothAdapter == null) { Log.w(TAG, "buildDisconnectedBluetoothDevice() BluetoothAdapter is null"); @@ -595,6 +630,13 @@ public class LocalMediaManager implements BluetoothCallback { return new ArrayList<>(mDisconnectedMediaDevices); } + private boolean isBondedMediaDevice(CachedBluetoothDevice cachedDevice) { + return cachedDevice != null + && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED + && !cachedDevice.isConnected() + && isMediaDevice(cachedDevice); + } + private boolean isMediaDevice(CachedBluetoothDevice device) { for (LocalBluetoothProfile profile : device.getConnectableProfiles()) { if (profile instanceof A2dpProfile || profile instanceof HearingAidProfile || diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt index 4b0c62bff60d..cc7d23e97d0c 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt @@ -106,7 +106,7 @@ class ViewHierarchyAnimator { ephemeral: Boolean ): Boolean { if ( - !isVisible( + !occupiesSpace( rootView.visibility, rootView.left, rootView.top, @@ -177,7 +177,7 @@ class ViewHierarchyAnimator { fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR ): Boolean { if ( - isVisible( + occupiesSpace( rootView.visibility, rootView.left, rootView.top, @@ -295,7 +295,7 @@ class ViewHierarchyAnimator { (view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel() - if (!isVisible(view.visibility, left, top, right, bottom)) { + if (!occupiesSpace(view.visibility, left, top, right, bottom)) { setBound(view, Bound.LEFT, left) setBound(view, Bound.TOP, top) setBound(view, Bound.RIGHT, right) @@ -362,7 +362,7 @@ class ViewHierarchyAnimator { duration: Long = DEFAULT_DURATION ): Boolean { if ( - !isVisible( + !occupiesSpace( rootView.visibility, rootView.left, rootView.top, @@ -530,17 +530,17 @@ class ViewHierarchyAnimator { } /** - * Returns whether the given [visibility] and bounds are consistent with a view being - * currently visible on screen. + * Returns whether the given [visibility] and bounds are consistent with a view being a + * contributing part of the hierarchy. */ - private fun isVisible( + private fun occupiesSpace( visibility: Int, left: Int, top: Int, right: Int, bottom: Int ): Boolean { - return visibility == View.VISIBLE && left != right && top != bottom + return visibility != View.GONE && left != right && top != bottom } /** diff --git a/packages/SystemUI/docs/user-file-manager.md b/packages/SystemUI/docs/user-file-manager.md new file mode 100644 index 000000000000..64f1694af50a --- /dev/null +++ b/packages/SystemUI/docs/user-file-manager.md @@ -0,0 +1,13 @@ +# UserFileManager + +This class is used to generate file paths and SharedPreferences that is compatible for multiple +users in SystemUI. Due to constraints in SystemUI, we can only read/write files as the system user. +Therefore, for secondary users, we want to store secondary user specific files into the system user +directory. + +## Handling User Removal + +This class will listen for Intent.ACTION_USER_REMOVED and remove directories that no longer +corresponding to active users. Additionally, upon start up, the class will run the same query for +deletion to ensure that there is no stale data. + diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags index e74b6c78ec80..5b9299c278a9 100644 --- a/packages/SystemUI/proguard.flags +++ b/packages/SystemUI/proguard.flags @@ -5,9 +5,9 @@ -keep class com.android.systemui.statusbar.car.CarStatusBar -keep class com.android.systemui.statusbar.phone.CentralSurfaces -keep class com.android.systemui.statusbar.tv.TvStatusBar --keep class com.android.systemui.car.CarSystemUIFactory --keep class com.android.systemui.SystemUIFactory --keep class com.android.systemui.tv.TvSystemUIFactory +-keep class ** extends com.android.systemui.SystemUIInitializer { + *; +} -keep class * extends com.android.systemui.CoreStartable -keep class * implements com.android.systemui.CoreStartable$Injector diff --git a/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml b/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml new file mode 100644 index 000000000000..159655e39d24 --- /dev/null +++ b/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="56dp" + android:height="24dp" + android:viewportWidth="56" + android:viewportHeight="24"> + <path + android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z" + android:fillColor="#5F6368"/> + <path + android:pathData="M21.872,5.873L20.926,6.813L21.492,7.38C21.392,7.566 21.332,7.773 21.332,8V16C21.332,16.733 21.932,17.333 22.666,17.333H30.666C30.892,17.333 31.099,17.273 31.286,17.173L33.186,19.073L34.126,18.133L31.999,16L21.872,5.873ZM31.999,10.986V8C31.999,7.266 31.399,6.666 30.666,6.666H24.552L25.886,8H30.666V12.78L31.999,14.113V13.013L34.666,15.666V8.333L31.999,10.986ZM22.666,8.553V16H30.112L22.666,8.553Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> +</vector> diff --git a/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml b/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml new file mode 100644 index 000000000000..087dde78833f --- /dev/null +++ b/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="56dp" + android:height="24dp" + android:viewportWidth="56" + android:viewportHeight="24"> + <path + android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z" + android:fillColor="#5F6368"/> + <path + android:pathData="M15.332,7.333C15.332,6.966 15.632,6.666 15.999,6.666C16.366,6.666 16.666,6.966 16.666,7.333V10.78L17.879,11.993C17.952,11.786 17.999,11.566 17.999,11.333V7.333C17.999,6.226 17.106,5.333 15.999,5.333C14.892,5.333 13.999,6.226 13.999,7.333V8.113L15.332,9.446V7.333ZM9.872,5.873L8.926,6.813L16.692,14.58C16.472,14.633 16.239,14.666 15.999,14.666C14.159,14.666 12.666,13.173 12.666,11.333H11.332C11.332,13.686 13.072,15.62 15.332,15.946V18H16.666V15.946C17.046,15.893 17.412,15.786 17.759,15.64L21.186,19.066L22.126,18.126L9.872,5.873ZM19.332,11.333H20.666C20.666,12.313 20.359,13.213 19.846,13.96L18.872,12.986C19.159,12.5 19.332,11.94 19.332,11.333Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> + <path + android:pathData="M33.872,5.873L32.926,6.813L33.492,7.38C33.392,7.566 33.332,7.773 33.332,8V16C33.332,16.733 33.932,17.333 34.666,17.333H42.666C42.892,17.333 43.099,17.273 43.286,17.173L45.186,19.073L46.126,18.133L43.999,16L33.872,5.873ZM43.999,10.986V8C43.999,7.266 43.399,6.666 42.666,6.666H36.552L37.886,8H42.666V12.78L43.999,14.113V13.013L46.666,15.666V8.333L43.999,10.986ZM34.666,8.553V16H42.112L34.666,8.553Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> +</vector> diff --git a/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml b/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml new file mode 100644 index 000000000000..693250d39f95 --- /dev/null +++ b/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="56dp" + android:height="24dp" + android:viewportWidth="56" + android:viewportHeight="24"> + <path + android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z" + android:fillColor="#5F6368"/> + <path + android:pathData="M27.807,7.133C27.807,6.767 28.107,6.467 28.473,6.467C28.84,6.467 29.14,6.767 29.14,7.133V10.58L30.353,11.793C30.427,11.587 30.473,11.367 30.473,11.133V7.133C30.473,6.027 29.58,5.133 28.473,5.133C27.367,5.133 26.473,6.027 26.473,7.133V7.913L27.807,9.247V7.133ZM22.347,5.673L21.4,6.613L29.167,14.38C28.947,14.433 28.713,14.467 28.473,14.467C26.633,14.467 25.14,12.973 25.14,11.133H23.807C23.807,13.487 25.547,15.42 27.807,15.747V17.8H29.14V15.747C29.52,15.693 29.887,15.587 30.233,15.44L33.66,18.867L34.6,17.927L22.347,5.673ZM31.807,11.133H33.14C33.14,12.113 32.833,13.013 32.32,13.76L31.347,12.787C31.633,12.3 31.807,11.74 31.807,11.133Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> +</vector> diff --git a/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml b/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml new file mode 100644 index 000000000000..8f9ecbe482e3 --- /dev/null +++ b/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt"> + <target android:name="_R_G_L_0_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="167" + android:propertyName="pathData" + android:startOffset="0" + android:valueFrom="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-5.98,-5.57 -6.46,-6.23 -6.83,-6.68 C-7.84,-6.64 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.88,6.1 5,5.23 C4.73,4.96 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c " + android:valueTo="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-6.02,-5.5 -6.69,-6.17 -7.12,-6.61 C-7.82,-6.41 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.79,6.11 4.97,5.37 C4.7,5.1 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c " + android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_D_1_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="17" + android:propertyName="fillAlpha" + android:startOffset="0" + android:valueFrom="0" + android:valueTo="1" + android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_D_1_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="167" + android:propertyName="pathData" + android:startOffset="0" + android:valueFrom="M-10.96 -7.79 C-10.96,-7.79 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -10.96,-7.79 -10.96,-7.79c " + android:valueTo="M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c " + android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="183" + android:propertyName="translateX" + android:startOffset="0" + android:valueFrom="0" + android:valueTo="1" + android:valueType="floatType" /> + </set> + </aapt:attr> + </target> + <aapt:attr name="android:drawable"> + <vector + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <group android:name="_R_G"> + <group + android:name="_R_G_L_0_G" + android:translateX="12" + android:translateY="12"> + <path + android:name="_R_G_L_0_G_D_0_P_0" + android:fillAlpha="1" + android:fillColor="#ffffff" + android:fillType="nonZero" + android:pathData=" M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c " /> + <path + android:name="_R_G_L_0_G_D_1_P_0" + android:fillAlpha="0" + android:fillColor="#ffffff" + android:fillType="nonZero" + android:pathData=" M-10.96 -7.79 C-10.96,-7.79 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -10.96,-7.79 -10.96,-7.79c " /> + </group> + </group> + <group android:name="time_group" /> + </vector> + </aapt:attr> +</animated-vector> diff --git a/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml b/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml new file mode 100644 index 000000000000..beb8b72d29ad --- /dev/null +++ b/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt"> + <target android:name="_R_G_L_0_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="167" + android:propertyName="pathData" + android:startOffset="0" + android:valueFrom="M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c " + android:valueTo="M7.44 10.62 C7.44,10.62 7.45,10.62 7.45,10.62 C7.45,10.62 8.85,9.22 8.85,9.22 C8.85,9.22 8.84,9.22 8.84,9.22 C8.84,9.22 7.44,10.62 7.44,10.62c " + android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.55,0 0.833,0.833 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_D_1_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="333" + android:propertyName="pathData" + android:startOffset="0" + android:valueFrom="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-6.02,-5.5 -6.69,-6.17 -7.12,-6.61 C-7.82,-6.41 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.79,6.11 4.97,5.37 C4.7,5.1 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c " + android:valueTo="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-5.98,-5.57 -6.46,-6.23 -6.83,-6.68 C-7.84,-6.64 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.88,6.1 5,5.23 C4.73,4.96 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c " + android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator + android:duration="350" + android:propertyName="translateX" + android:startOffset="0" + android:valueFrom="0" + android:valueTo="1" + android:valueType="floatType" /> + </set> + </aapt:attr> + </target> + <aapt:attr name="android:drawable"> + <vector + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <group android:name="_R_G"> + <group + android:name="_R_G_L_0_G" + android:translateX="12" + android:translateY="12"> + <path + android:name="_R_G_L_0_G_D_0_P_0" + android:fillAlpha="1" + android:fillColor="#ffffff" + android:fillType="nonZero" + android:pathData=" M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c " /> + <path + android:name="_R_G_L_0_G_D_1_P_0" + android:fillAlpha="1" + android:fillColor="#ffffff" + android:fillType="nonZero" + android:pathData=" M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c " /> + </group> + </group> + <group android:name="time_group" /> + </vector> + </aapt:attr> +</animated-vector> diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml index d0f4903a3421..70a770912c7f 100644 --- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml +++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml @@ -70,15 +70,32 @@ android:visibility="gone" android:contentDescription="@string/dream_overlay_status_bar_wifi_off" /> - <com.android.systemui.dreams.DreamOverlayDotImageView + <ImageView + android:id="@+id/dream_overlay_mic_off" + android:layout_width="@dimen/dream_overlay_grey_chip_width" + android:layout_height="match_parent" + android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin" + android:src="@drawable/dream_overlay_mic_off" + android:visibility="gone" + android:contentDescription="@string/dream_overlay_status_bar_mic_off" /> + + <ImageView + android:id="@+id/dream_overlay_camera_off" + android:layout_width="@dimen/dream_overlay_grey_chip_width" + android:layout_height="match_parent" + android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin" + android:src="@drawable/dream_overlay_camera_off" + android:visibility="gone" + android:contentDescription="@string/dream_overlay_status_bar_camera_off" /> + + <ImageView android:id="@+id/dream_overlay_camera_mic_off" - android:layout_width="@dimen/dream_overlay_camera_mic_off_indicator_size" - android:layout_height="@dimen/dream_overlay_camera_mic_off_indicator_size" - android:layout_gravity="center_vertical" + android:layout_width="@dimen/dream_overlay_grey_chip_width" + android:layout_height="match_parent" android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin" + android:src="@drawable/dream_overlay_mic_and_camera_off" android:visibility="gone" - android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off" - app:dotColor="@color/dream_overlay_camera_mic_off_dot_color" /> + android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off" /> </LinearLayout> </com.android.systemui.dreams.DreamOverlayStatusBarView> diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml index eb43853abdec..93c16e4e119d 100644 --- a/packages/SystemUI/res/layout/media_output_dialog.xml +++ b/packages/SystemUI/res/layout/media_output_dialog.xml @@ -42,12 +42,35 @@ android:layout_height="wrap_content" android:paddingStart="12dp" android:orientation="vertical"> - <ImageView - android:id="@+id/app_source_icon" - android:layout_width="20dp" - android:layout_height="20dp" + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" android:gravity="center_vertical" - android:importantForAccessibility="no"/> + android:orientation="horizontal"> + <ImageView + android:id="@+id/app_source_icon" + android:layout_width="20dp" + android:layout_height="20dp" + android:gravity="center_vertical" + android:importantForAccessibility="no"/> + + <Space + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="match_parent"/> + + <ImageView + android:id="@+id/broadcast_icon" + android:src="@drawable/settings_input_antenna" + android:contentDescription="@string/broadcasting_description_is_broadcasting" + android:layout_width="48dp" + android:layout_height="48dp" + android:padding="12dp" + android:gravity="center_vertical" + android:clickable="true" + android:focusable="true" + android:visibility="gone"/> + </LinearLayout> <TextView android:id="@+id/header_title" android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 4d5bf53eb64a..6423a50fc107 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -18,7 +18,7 @@ --> -<com.android.systemui.statusbar.phone.NotificationPanelView +<com.android.systemui.shade.NotificationPanelView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/notification_panel" @@ -67,7 +67,7 @@ </com.android.keyguard.LockIconView> - <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer + <com.android.systemui.shade.NotificationsQuickSettingsContainer android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="@integer/notification_panel_layout_gravity" @@ -150,11 +150,11 @@ android:text="@string/tap_again" android:visibility="gone" /> - </com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer> + </com.android.systemui.shade.NotificationsQuickSettingsContainer> <FrameLayout android:id="@+id/preview_container" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> -</com.android.systemui.statusbar.phone.NotificationPanelView> +</com.android.systemui.shade.NotificationPanelView> diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml index 60860bad9c64..86f8ce26ccab 100644 --- a/packages/SystemUI/res/layout/super_notification_shade.xml +++ b/packages/SystemUI/res/layout/super_notification_shade.xml @@ -18,7 +18,7 @@ --> <!-- This is the notification shade window. --> -<com.android.systemui.statusbar.phone.NotificationShadeWindowView +<com.android.systemui.shade.NotificationShadeWindowView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:sysui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" @@ -114,4 +114,4 @@ android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> -</com.android.systemui.statusbar.phone.NotificationShadeWindowView> +</com.android.systemui.shade.NotificationShadeWindowView> diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml index 0f2d372f7158..c2c79cb0f34b 100644 --- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml +++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -<androidx.constraintlayout.widget.ConstraintLayout +<com.android.systemui.user.UserSwitcherRootView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" @@ -68,4 +68,4 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHeight_min="48dp" /> -</androidx.constraintlayout.widget.ConstraintLayout> +</com.android.systemui.user.UserSwitcherRootView> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index f772e75bf653..3d27dfd95760 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Tik weer"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk die onsluitikoon om oop te maak"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontsluit met gesig. Druk die ontsluitikoon om oop te maak."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontsluit met gesig. Druk om oop te maak."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesig is herken. Druk om oop te maak."</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index b3f5d39a3101..78873e529f13 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ለመክፈት የመክፈቻ አዶውን ይጫኑ"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"በመልክ ተከፍቷል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"በመልክ ተከፍቷል። ለመክፈት ይጫኑ።"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"መልክ ተለይቶ ታውቋል። ለመክፈት ይጫኑ።"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 5bc1f89a9a86..98ab7a4b8836 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"اضغط على رمز فتح القفل لفتح قفل الشاشة."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"تم فتح القفل بالتعرّف على وجهك. لفتح الجهاز، اضغط على رمز فتح القفل."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط لفتح الجهاز."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"تم التعرّف على الوجه. اضغط لفتح الجهاز."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index f411b7d9e533..564fd1b11ff1 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ টিপক।"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ টিপক।"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index fe542c1a79b4..4ce451c86ed1 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Yenidən toxunun"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"\"Kilidi aç\" ikonasına basıb açın"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb açın."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Üz ilə kiliddən çıxarılıb. Açmaq üçün basın."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Üz tanınıb. Açmaq üçün basın."</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 873663bc0e59..e87cc5effbcf 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja da biste otvorili."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 7e595c951054..5779cb3ace7e 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Каб адкрыць, націсніце значок разблакіроўкі"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблакіравана распазнаваннем твару. Націсніце, каб адкрыць."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Твар распазнаны. Націсніце, каб адкрыць."</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index d32b85a8623c..1784939b8f2d 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Натиснете иконата за отключване, за да отворите"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отключено с лице. Натиснете иконата за отключване, за да отворите."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отключено с лице. Натиснете за отваряне."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето бе разпознато. Натиснете за отваряне."</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 7b5a7d88d42f..dfc8a2b714ad 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য প্রেস করুন।"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য প্রেস করুন।"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index c1d20e3a66b2..1ae04fedbf03 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Ponovo dodirnite"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu za otključavanje da otvorite."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano licem. Pritisnite ikonu za otklj. da otvorite."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano licem. Pritisnite da otvorite."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice prepoznato. Pritisnite da otvorite."</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 137b04733c07..0899d882edec 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Torna a tocar"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prem la icona de desbloqueig per obrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S\'ha desbloquejat amb la cara. Prem la icona per obrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S\'ha desbloquejat amb la cara. Prem per obrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"S\'ha reconegut la cara. Prem per obrir."</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index e0fa698f85aa..db653160c64d 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Znovu klepněte"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Otevřete klepnutím na ikonu odemknutí"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odemknuto obličejem. Stisknutím otevřete."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obličej rozpoznán. Stisknutím otevřete."</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index c52fc71c79d4..c1e364b2745b 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Tryk igen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryk på oplåsningsikonet for at åbne"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at åbne."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst op ved hjælp af ansigt. Tryk for at åbne."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansigt genkendt. Tryk for at åbne."</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 815b231307f0..618901cae413 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Noch einmal tippen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tippe zum Öffnen auf das Symbol „Entsperren“"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesicht erkannt. Tippe zum Öffnen."</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 225f7ec20d47..4a15ede13596 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Πατήστε το εικονίδιο ξεκλειδώματος για άνοιγμα"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ξεκλείδωμα με πρόσωπο. Πατήστε το εικονίδιο ξεκλειδώματος."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για άνοιγμα."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για άνοιγμα."</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index ccb0a284b2b2..634a9daa2abe 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -307,6 +307,7 @@ <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string> + <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 4b14e1f68ca6..f0e2208a22d0 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -307,6 +307,7 @@ <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string> + <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index ccb0a284b2b2..634a9daa2abe 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -307,6 +307,7 @@ <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string> + <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index ccb0a284b2b2..634a9daa2abe 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -307,6 +307,7 @@ <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string> + <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 4418230539bd..1418095fbfe6 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -307,6 +307,7 @@ <string name="tap_again" msgid="1315420114387908655">"Tap again"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string> + <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognized. Press to open."</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 8140bda8fd4d..26d980169833 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Presiona otra vez"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Presiona el ícono de desbloquear para abrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueo con rostro. Presiona el ícono para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueo con rostro. Presiona para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rostro reconocido. Presiona para abrir."</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 955bb116865e..1876d77f2238 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Toca de nuevo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pulsa el icono desbloquear para abrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado con la cara. Toca el icono de desbloquear para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado con la cara. Pulsa para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Cara reconocida. Pulsa para abrir."</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 61ca78df4945..c64fef9cba6b 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Puudutage uuesti"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Avamiseks vajutage avamise ikooni"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avati näoga. Avamiseks vajutage avamise ikooni."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avati näoga. Avamiseks vajutage."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nägu tuvastati. Avamiseks vajutage."</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 3b051e52d105..0c1302ebb982 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Sakatu berriro"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Irekitzeko, sakatu desblokeatzeko ikonoa"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Aurpegiaren bidez desblokeatu da. Irekitzeko, sakatu desblokeatzeko ikonoa."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Aurpegiaren bidez desblokeatu da. Sakatu irekitzeko."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ezagutu da aurpegia. Sakatu irekitzeko."</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 03191a866262..bd0b037bf291 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند بهبالا بکشید"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفلگشایی را فشار دهید"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"قفلْ با چهره باز شد. برای باز کردن، نماد قفلگشایی را فشار دهید."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"قفلْ با چهره باز شد. برای باز کردن، فشار دهید."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چهره شناسایی شد. برای باز کردن، فشار دهید."</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index ba9f9afc6e9c..329cc44b4e23 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Napauta uudelleen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Jatka painamalla lukituksen avauskuvaketta."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avattu kasvojen avulla. Avaa painamalla."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Kasvot tunnistettu. Avaa painamalla."</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index eb2081071de9..1fc6b8c9ecd9 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône Déverrouiller pour ouvrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverr. par reconn. faciale. App. sur l\'icône pour ouvrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverr. par reconnaissance faciale. Appuyez pour ouvrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 1c6943f9a207..79acfdbdb882 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Appuyer à nouveau"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône de déverrouillage pour ouvrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé par visage. Appuyez sur icône déverrouillage pour ouvrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverrouillé par visage. Appuyez pour ouvrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 9258be9a5d8c..e73aa032171a 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Toca de novo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Preme a icona de desbloquear para abrir a porta"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Usouse o desbloqueo facial. Preme para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Recoñeceuse a cara. Preme para abrir."</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index f3cc2dd7eaff..e00f5ff22297 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા \'અનલૉક કરો\' આઇકન દબાવો."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે દબાવો."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ચહેરો ઓળખ્યો. ખોલવા માટે દબાવો."</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 15612080da5c..b74d2874fcad 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहरे से अनलॉक किया. डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहरे से अनलॉक किया गया. डिवाइस खोलने के लिए टैप करें."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए टैप करें."</string> @@ -950,10 +952,7 @@ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट बदलें"</string> <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string> - <!-- no translation found for dream_date_complication_date_format (8191225366513860104) --> - <skip /> - <!-- no translation found for dream_time_complication_12_hr_time_format (4691197486690291529) --> - <skip /> - <!-- no translation found for dream_time_complication_24_hr_time_format (6248280719733640813) --> - <skip /> + <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string> + <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string> + <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 01ad02b69356..823d2f495d2a 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste otvorili."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano pomoću lica. Pritisnite da biste otvorili."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 8d33bc8f4c56..12e2d70de609 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Koppintson újra"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Az eszköz használatához nyomja meg a feloldás ikonját"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Arccal feloldva. A megnyitáshoz nyomja meg a feloldás ikont."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Zárolás arccal feloldva. Koppintson az eszköz használatához."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Arc felismerve. Koppintson az eszköz használatához."</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index c69ee42cd85f..c702969c9058 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Բացեք՝ սեղմելով ապակողպման պատկերակը"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ապակողպվել է դեմքով։ Բացեք՝ սեղմելով ապակողպման պատկերակը։"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ապակողպվել է դեմքով։ Սեղմեք բացելու համար։"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Դեմքը ճանաչվեց։ Սեղմեք բացելու համար։"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 19b9d40e84fe..e52d08d7f721 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Ketuk lagi"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk membuka"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk membuka."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Kunci dibuka dengan wajah. Tekan untuk membuka."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dikenali. Tekan untuk membuka."</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 93ed60375bbd..e8d2d866aec3 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Ýttu aftur"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ýttu á táknið til að taka úr lás til að opna"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Opnað með andliti. Ýttu á táknið taka úr lás til að opna."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Opnað með andliti. Ýttu til að opna."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Andlitið var greint. Ýttu til að opna."</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 02917338874e..5d318bfb1adf 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Tocca di nuovo"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Premi l\'icona Sblocca per aprire"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Sbloccato con il volto. Premi l\'icona Sblocca per aprire."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Sbloccato con il volto. Premi per aprire."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Volto riconosciuto. Premi per aprire."</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 6a0199c66e3c..25e08c634b6b 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"הנעילה בוטלה בזיהוי פנים. פותחים בלחיצה על סמל ביטול הנעילה."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי לפתוח."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"הפנים זוהו. יש ללחוץ כדי לפתוח."</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 3a34f3c2206e..69a959268d7f 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"顔でロック解除しました。アイコンを押すと開きます。"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"顔でロック解除しました。押すと開きます。"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"顔を認識しました。押すと開きます。"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 57b56f7b57e7..fc1ecdac36ee 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"გასახსნელად დააჭირეთ განბლოკვის ხატულას"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"განიბლოკა სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"განიბლოკა სახით. დააჭირეთ გასახსნელად."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ამოცნობილია სახით. დააჭირეთ გასახსნელად."</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index e14c8274d125..d47c26df09a8 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Бет үлгісі арқылы ашылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Бетпен ашылды. Ашу үшін басыңыз."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Бет танылды. Ашу үшін басыңыз."</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 14fa8de52289..48fedd222a1f 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ចុចម្ដងទៀត"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើដើម្បីបើក"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"បានដោះសោដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបើក។"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបើក។"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index f980937cca84..55afb910c775 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index cd88795f771b..32d345f04532 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string> <string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"얼굴 인식으로 잠금 해제되었습니다. 기기를 열려면 잠금 해제 아이콘을 누르세요."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"얼굴 인식으로 잠금 해제되었습니다. 열려면 누르세요."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"얼굴이 인식되었습니다. 열려면 누르세요."</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 391311159d34..a9670589f0cc 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Кулпуну ачуу сүрөтчөсүн басыңыз"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Кулпуну жүзүңүз менен ачтыңыз. Эми кулпуну ачуу сүрөтчөсүн басыңыз."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Кулпуну жүзүңүз менен ачтыңыз. Ачуу үчүн басыңыз."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Жүз таанылды. Ачуу үчүн басыңыз."</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 469f77bf60d0..d86198e4d512 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ກົດໄອຄອນປົດລັອກເພື່ອເປີດ"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອເປີດ."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອເປີດ."</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 66c9c3466f6a..56bfb2c3713c 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Palieskite dar kartą"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Paspauskite atrakinimo piktogramą, kad atidarytumėte"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atrakinta pagal veidą. Pasp. atr. pikt., kad atidarytumėte."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Atrakinta pagal veidą. Paspauskite, kad atidarytumėte."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Veidas atpažintas. Paspauskite, kad atidarytumėte."</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a32c5e41be30..65e7c5d74b39 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Pieskarieties vēlreiz"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Lai atvērtu, nospiediet atbloķēšanas ikonu"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atbloķēta ar seju. Atvērt: nospiediet atbloķēšanas ikonu."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ierīce atbloķēta ar seju. Nospiediet, lai atvērtu."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Seja atpazīta. Nospiediet, lai atvērtu."</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index d7951b190241..85f9cd5329d0 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отклучено со лик. Притиснете ја иконата за отклучување за да отворите."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отклучено со лик. Притиснете за да отворите."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето е препознаено. Притиснете за да отворите."</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 5b0164d8e3be..49a807545283 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്തു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്തു. തുറക്കാൻ അമർത്തുക."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അമർത്തുക."</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 2648c5c2477d..c9bd0bf20243 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Царайгаар түгжээг тайлсан. Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Царайгаар түгжээг тайлсан. Нээхийн тулд дарна уу."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Царайг таньсан. Нээхийн тулд дарна уу."</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 7129762b6e58..5922126dcebe 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी दाबा."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी दाबा."</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index e37d88cd4f8a..ac6f3deb8e53 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Ketik sekali lagi"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk buka"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk buka."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Dibuka kunci dengan wajah. Tekan untuk membuka."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dicam. Tekan untuk membuka."</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 301d42e2e3c3..09de7451064f 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"မျက်နှာပြ လော့ခ်ဖွင့်ထားသည်။ လော့ခ်ဖွင့်သင်္ကေတ နှိပ်၍ဝင်ပါ။"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 64bc528fc71f..8b435c2fd43d 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -133,7 +133,7 @@ <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string> <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string> <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string> - <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string> + <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string> <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string> <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string> <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string> @@ -307,7 +307,9 @@ <string name="tap_again" msgid="1315420114387908655">"Trykk igjen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Trykk på lås opp-ikonet for å åpne"</string> - <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> + <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst opp med ansiktet. Trykk for å åpne."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet er gjenkjent. Trykk for å åpne."</string> <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 4db5278a170d..05bb2868125c 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न अनलक आइकनमा थिच्नुहोस्।"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"अनुहार प्रयोग गरी अनलक गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"अनुहार पहिचान गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 07c53c513c73..2c91600cc5e5 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Tik nog een keer"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk op het ontgrendelicoon om te openen"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontgrendeld via gezicht. Druk om te openen."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gezicht herkend. Druk om te openen."</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 7eda9bc84dd3..f30f7d13d0f7 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -79,8 +79,8 @@ <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ସ୍କ୍ରିନସଟକୁ ସେଭ୍ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ଆପ୍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string> <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ନେବା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</string> - <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ୍ କରନ୍ତୁ"</string> - <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ୍ କରନ୍ତୁ"</string> + <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ କରନ୍ତୁ"</string> + <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ କରନ୍ତୁ"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"ସ୍କ୍ରିନସଟ ସେୟାର କରନ୍ତୁ"</string> <string name="screenshot_scroll_label" msgid="2930198809899329367">"ଅଧିକ କ୍ୟାପଚର୍ କରନ୍ତୁ"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string> @@ -124,10 +124,10 @@ <string name="accessibility_lock_icon" msgid="661492842417875775">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string> - <string name="cancel" msgid="1089011503403416730">"ବାତିଲ୍ କରନ୍ତୁ"</string> + <string name="cancel" msgid="1089011503403416730">"ବାତିଲ କରନ୍ତୁ"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> - <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> + <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"ଆପଣଙ୍କର ମୁହଁକୁ ପ୍ରମାଣ କରୁଛି"</string> <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string> @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string> @@ -619,7 +621,7 @@ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ଟାଇଲ୍ ପୁଣି ସଜାଇବାକୁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string> <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍ କରନ୍ତୁ"</string> <string name="drag_to_remove_disabled" msgid="933046987838658850">"ଆପଣଙ୍କର ଅତିକମ୍ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string> - <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ୍ କରନ୍ତୁ"</string> + <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ କରନ୍ତୁ"</string> <string name="tuner_time" msgid="2450785840990529997">"ସମୟ"</string> <string-array name="clock_options"> <item msgid="3986445361435142273">"ଘଣ୍ଟା, ମିନିଟ୍ ଏବଂ ସେକେଣ୍ଡ ଦେଖାନ୍ତୁ"</item> @@ -651,7 +653,7 @@ <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ଉପଯୋଗକର୍ତ୍ତା ବାଛନ୍ତୁ"</string> <string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍ କନେକ୍ସନ୍ ନାହିଁ"</string> <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string> - <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଙ୍ଗର କ୍ରମ ସଂଶୋଧନ କରନ୍ତୁ।"</string> + <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଂସର କ୍ରମ ଏଡିଟ କରନ୍ତୁ।"</string> <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ୍ ସ୍କ୍ରୀନ୍"</string> @@ -823,7 +825,7 @@ <string name="controls_error_generic" msgid="352500456918362905">"ସ୍ଥିତି ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string> <string name="controls_menu_add" msgid="4447246119229920050">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରନ୍ତୁ"</string> - <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ୍ କରନ୍ତୁ"</string> + <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ଆଉଟପୁଟ୍ ଯୋଗ କରନ୍ତୁ"</string> <string name="media_output_dialog_group" msgid="5571251347877452212">"ଗୋଷ୍ଠୀ"</string> <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string> @@ -935,7 +937,7 @@ <string name="clipboard_editor" msgid="2971197550401892843">"କ୍ଲିପବୋର୍ଡ ଏଡିଟର"</string> <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"କ୍ଲିପବୋର୍ଡ"</string> <string name="clipboard_image_preview" msgid="2156475174343538128">"ଇମେଜ ପ୍ରିଭ୍ୟୁ"</string> - <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ କରନ୍ତୁ"</string> <string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string> <string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 425e66472b47..d41e43c3c935 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string> @@ -362,7 +364,7 @@ <string name="notification_section_header_gentle" msgid="6804099527336337197">"ਸ਼ਾਂਤ"</string> <string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string> - <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string> + <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string> <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string> <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index ccf51800d2ed..36bbbc4ccbc0 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Kliknij jeszcze raz"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Aby otworzyć, kliknij ikonę odblokowywania"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odblokowano skanem twarzy. Aby otworzyć, kliknij ikonę odblokowywania."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odblokowano rozpoznawaniem twarzy. Naciśnij, by otworzyć."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Twarz rozpoznana. Naciśnij, by otworzyć."</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 1fa4954ccb58..0cb7420785ba 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 7f24b90448f0..9702b9759793 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prima o ícone de desbloqueio para abrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueio com a face. Prima ícone de desbloqueio p/ abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado com o rosto. Prima para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Prima para abrir."</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 1fa4954ccb58..0cb7420785ba 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 80cdb953b527..99d2f06b2970 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Atingeți din nou"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Apăsați pictograma de deblocare pentru a deschide"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S-a deblocat cu ajutorul feței. Apăsați pictograma de deblocare pentru a deschide"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S-a deblocat cu ajutorul feței. Apăsați pentru a deschide."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Chipul a fost recunoscut. Apăsați pentru a deschide."</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index dd5e0e5a9561..817fdc0e275d 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нажмите на значок разблокировки."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Сканирование выполнено. Нажмите на значок разблокировки."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблокировано сканированием лица. Нажмите, чтобы открыть."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицо распознано. Нажмите, чтобы открыть."</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index b2c393f6c16d..8c7b85cbe287 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ඔබන්න."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට ඔබන්න."</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 542f197cf429..4bdd20601559 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Klepnite znova"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Otvorte klepnutím na ikonu odomknutia"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odomknuté tvárou. Otvorte klepnutím na ikonu odomknutia."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odomknuté tvárou. Otvorte stlačením."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Tvár bola rozpoznaná. Otvorte stlačením."</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 9dfc7cc3c618..c1afc12ccc54 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Znova se dotaknite možnosti"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Za odpiranje pritisnite ikono za odklepanje."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odklenjeno z obrazom. Za odpiranje pritisnite ikono za odklepanje."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odklenjeno z obrazom. Pritisnite za odpiranje."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obraz je prepoznan. Pritisnite za odpiranje."</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 8417ee640566..c3cdf21857c3 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Trokit sërish"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Shtyp ikonën e shkyçjes për ta hapur"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për ta hapur."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"U shkyç me fytyrë. Shtyp për ta hapur."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Fytyra u njoh. Shtyp për ta hapur."</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 3bb3bfb1124c..ef5993bd9fdd 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања да бисте отворили."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index b7f9b05ad4b6..20bc29fc77ce 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Tryck igen"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryck på ikonen lås upp för att öppna"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att öppna."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Upplåst med ansiktslås. Tryck för att öppna."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet har identifierats. Tryck för att öppna."</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 1f5b7eac04c1..418b88eede96 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Gusa tena"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Bonyeza aikoni ya kufungua ili ufungue"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili ufungue."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili ufungue."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Uso umetambuliwa. Bonyeza ili ufungue."</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 8fea33e79de8..34cb0cf9de5b 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க, அன்லாக் ஐகானை அழுத்துக."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க அழுத்தவும்."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அழுத்தவும்."</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 759ebb471bb5..720c909b5223 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -50,7 +50,7 @@ <string name="usb_debugging_title" msgid="8274884945238642726">"USB డీబగ్గింగ్ను అనుమతించాలా?"</string> <string name="usb_debugging_message" msgid="5794616114463921773">"ఇది కంప్యూటర్ యొక్క RSA కీ వేలిముద్ర:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string> <string name="usb_debugging_always" msgid="4003121804294739548">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించు"</string> - <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించు"</string> + <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించండి"</string> <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB డీబగ్గింగ్కి అనుమతి లేదు"</string> <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string> <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"మీరు సిస్టమ్ భాషను <xliff:g id="LANGUAGE">%1$s</xliff:g> భాషకు మార్చాలనుకుంటున్నారా?"</string> @@ -60,7 +60,7 @@ <string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్వర్క్ ద్వారా వైర్లెస్ డీబగ్గింగ్ను అనుమతించాలా?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi అడ్రస్ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్వర్క్ నుండి ఎల్లప్పుడూ అనుమతించు"</string> - <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించు"</string> + <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించండి"</string> <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"వైర్లెస్ డీబగ్గింగ్కి అనుమతి లేదు"</string> <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్, వైర్లెస్ డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక యూజర్ కి స్విచ్ అవ్వండి."</string> <string name="usb_contaminant_title" msgid="894052515034594113">"USB పోర్ట్ నిలిపివేయబడింది"</string> @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్లాక్ చిహ్నాన్ని నొక్కండి"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ముఖం ద్వారా అన్లాక్ చేయబడింది. తెరవడానికి అన్లాక్ చిహ్నాన్ని నొక్కండి."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ముఖం ద్వారా అన్లాక్ చేయబడింది. తెరవడానికి నొక్కండి."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ముఖం గుర్తించబడింది. తెరవడానికి నొక్కండి."</string> @@ -712,7 +714,7 @@ <string name="slice_permission_text_1" msgid="6675965177075443714">"- ఇది <xliff:g id="APP">%1$s</xliff:g> నుండి సమాచారాన్ని చదువుతుంది"</string> <string name="slice_permission_text_2" msgid="6758906940360746983">"- ఇది <xliff:g id="APP">%1$s</xliff:g> లోపల చర్యలు తీసుకుంటుంది"</string> <string name="slice_permission_checkbox" msgid="4242888137592298523">"ఏ యాప్ నుండి అయినా స్లైస్లను చూపించడానికి <xliff:g id="APP">%1$s</xliff:g>ని అనుమతించండి"</string> - <string name="slice_permission_allow" msgid="6340449521277951123">"అనుమతించు"</string> + <string name="slice_permission_allow" msgid="6340449521277951123">"అనుమతించండి"</string> <string name="slice_permission_deny" msgid="6870256451658176895">"తిరస్కరించు"</string> <string name="auto_saver_title" msgid="6873691178754086596">"బ్యాటరీ సేవర్ని షెడ్యూల్ చేయడానికి నొక్కండి"</string> <string name="auto_saver_text" msgid="3214960308353838764">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string> @@ -818,7 +820,7 @@ <string name="controls_error_timeout" msgid="794197289772728958">"ఇన్యాక్టివ్, యాప్ చెక్ చేయండి"</string> <string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string> - <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ను యాక్సెస్ చేయడం సాధ్యపడలేదు. <xliff:g id="APPLICATION">%2$s</xliff:g> యాప్ను తనిఖీ చేసి, కంట్రోల్ ఇప్పటికీ అందుబాటులో ఉందని, యాప్ సెట్టింగ్లు మారలేదని నిర్ధారించుకోండి."</string> + <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ను యాక్సెస్ చేయడం సాధ్యపడలేదు. <xliff:g id="APPLICATION">%2$s</xliff:g> యాప్ను చెక్ చేసి, కంట్రోల్ ఇప్పటికీ అందుబాటులో ఉందని, యాప్ సెట్టింగ్లు మారలేదని నిర్ధారించుకోండి."</string> <string name="controls_open_app" msgid="483650971094300141">"యాప్ను తెరువు"</string> <string name="controls_error_generic" msgid="352500456918362905">"స్టేటస్ లోడ్ చేయడం సాధ్యపడలేదు"</string> <string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string> diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml index 94f6c3952e06..375bd394bb4c 100644 --- a/packages/SystemUI/res/values-television/config.xml +++ b/packages/SystemUI/res/values-television/config.xml @@ -22,7 +22,7 @@ <resources> <!-- SystemUIFactory component --> <string name="config_systemUIFactoryComponent" translatable="false"> - com.android.systemui.tv.TvSystemUIFactory + com.android.systemui.tv.TvSystemUIInitializer </string> <!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. --> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 99c2e32a6947..8958be0ea95a 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"กดไอคอนปลดล็อกเพื่อเปิด"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อเปิด"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อเปิด"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"จดจำใบหน้าได้ กดเพื่อเปิด"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 2943313eb071..134005c85545 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"I-tap ulit"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pindutin ang icon ng unlock para buksan"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para buksan."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Na-unlock gamit ang mukha. Pindutin para buksan."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nakilala ang mukha. Pindutin para buksan."</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 00569a0b5f5c..fb928b2f5c4a 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Tekrar dokunun"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Açmak için Kilit açma simgesine basın"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Cihazın kilidini yüzünüzle açtınız. Açmak için basın."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yüzünüz tanındı. Açmak için basın."</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 85573a925293..3df26f662787 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейсконтроль). Натисніть, щоб відкрити."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Обличчя розпізнано. Натисніть, щоб відкрити."</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index d9d1cbd12fb3..40e0bb3e3148 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"کھولنے کیلئے انلاک آئیکن دبائیں"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"چہرے سے انلاک کیا گیا۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"چہرے سے انلاک کیا گیا۔ کھولنے کے لیے دبائیں۔"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چہرے کی شناخت ہو گئی۔ کھولنے کے لیے دبائیں۔"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 65a3e5113902..a6490f429742 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Yana bosing"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ochish uchun ochish belgisini bosing"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Yuz orqali ochilgan. Ochish uchun ochish belgisini bosing."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Yuz orqali ochildi. Ochish uchun bosing."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yuz aniqlandi. Ochish uchun bosing."</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 7340db2fe58d..3a579f15ead4 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Nhấn lại"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Nhấn biểu tượng mở khoá để mở"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Đã mở khoá bằng khuôn mặt. Nhấn vào biểu tượng mở khoá để mở."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Đã mở khoá bằng khuôn mặt. Nhấn để mở."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Đã nhận diện khuôn mặt. Nhấn để mở."</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 96d895832bfe..b46406e9d31e 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下解锁图标即可打开"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已通过面孔识别解锁。按下解锁图标即可打开。"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已通过面孔识别解锁。点按即可打开。"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"识别出面孔。点按即可打开。"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 89c7c29e4494..1958d0df7401 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"再次輕按"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"按解鎖圖示即可開啟"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已使用面孔解鎖。按解鎖圖示即可開啟。"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已使用面孔解鎖。按下即可開啟。"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"已識別面孔。按下即可開啟。"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 9e22840d6478..22d0544f3314 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下「解鎖」圖示即可開啟"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"裝置已透過人臉解鎖,按下「解鎖」圖示即可開啟。"</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"裝置已透過你的臉解鎖,按下即可開啟。"</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"臉孔辨識完成,按下即可開啟。"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index a6e302664728..4000ce00de59 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -307,6 +307,8 @@ <string name="tap_again" msgid="1315420114387908655">"Thepha futhi"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"Cindezela isithonjana sokuvula ukuze uvule"</string> + <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) --> + <skip /> <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uvule."</string> <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Vula ngobuso. Cindezela ukuze uvule."</string> <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ubuso buyaziwa. Cindezela ukuze uvule."</string> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 771973c36053..82a3b58a5155 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -286,7 +286,7 @@ <bool name="config_enableFullscreenUserSwitcher">false</bool> <!-- SystemUIFactory component --> - <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string> + <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIInitializerImpl</string> <!-- QS tile shape store width. negative implies fill configuration instead of stroke--> <dimen name="config_qsTileStrokeWidthActive">-1dp</dimen> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index bb5c5928181a..022a6b2f4da2 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1449,6 +1449,7 @@ @*android:dimen/status_bar_system_icon_size</dimen> <dimen name="dream_overlay_camera_mic_off_indicator_size">8dp</dimen> <dimen name="dream_overlay_notification_indicator_size">6dp</dimen> + <dimen name="dream_overlay_grey_chip_width">56dp</dimen> <!-- Dream overlay complications related dimensions --> <dimen name="dream_overlay_complication_clock_time_text_size">100sp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index ef672f3a6213..9c2542cbd05f 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -802,6 +802,8 @@ <!-- Message shown when lock screen is unlocked (ie: by trust agent) and the user taps the empty space on the lock screen and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] --> <string name="keyguard_unlock_press">Press the unlock icon to open</string> + <!-- Message shown when non-bypass face authentication succeeds. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] --> + <string name="keyguard_face_successful_unlock_swipe">Unlocked by face. Swipe up to open.</string> <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] --> <string name="keyguard_face_successful_unlock_press">Unlocked by face. Press the unlock icon to open.</string> <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] --> @@ -2295,8 +2297,8 @@ <string name="media_output_dialog_disconnected">(disconnected)</string> <!-- Summary for connecting error message [CHAR LIMIT=NONE] --> <string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string> - <!-- Title for pairing item [CHAR LIMIT=60] --> - <string name="media_output_dialog_pairing_new">Pair new device</string> + <!-- Title for connecting item [CHAR LIMIT=60] --> + <string name="media_output_dialog_pairing_new">Connect a device</string> <!-- Title for launch app [CHAR LIMIT=60] --> <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string> <!-- App name when can't get app name [CHAR LIMIT=60] --> @@ -2553,6 +2555,10 @@ <string name="dream_overlay_status_bar_priority_mode">Priority mode</string> <!-- Content description for the alarm set icon in the dream overlay status bar [CHAR LIMIT=NONE] --> <string name="dream_overlay_status_bar_alarm_set">Alarm set</string> + <!-- Content description for the camera off icon in the dream overlay status bar [CHAR LIMIT=NONE] --> + <string name="dream_overlay_status_bar_camera_off">Camera is off</string> + <!-- Content description for the mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] --> + <string name="dream_overlay_status_bar_mic_off">Mic is off</string> <!-- Content description for the camera and mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] --> <string name="dream_overlay_status_bar_camera_mic_off">Camera and mic are off</string> <!-- Content description for the notifications indicator icon in the dream overlay status bar [CHAR LIMIT=NONE] --> @@ -2560,6 +2566,10 @@ =1 {# notification} other {# notifications} }</string> + <!-- Accessibility label for weather complication on dreams with weather condition and temperature [CHAR_LIMIT=200] --> + <string name="dream_overlay_weather_complication_desc"> + <xliff:g id="weather_condition" example="Partly cloudy">%1$s</xliff:g>, <xliff:g id="temperature" example="7°C">%2$s</xliff:g> + </string> <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is broadcasting --> <string name="broadcasting_description_is_broadcasting">Broadcasting</string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index c5beaa7ee0b1..916526d0efac 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -130,13 +130,6 @@ public class ActivityManagerWrapper { } /** - * @return a list of the recents tasks. - */ - public List<RecentTaskInfo> getRecentTasks(int numTasks, int userId) { - return mAtm.getRecentTasks(numTasks, RECENT_IGNORE_UNAVAILABLE, userId); - } - - /** * @return a {@link ThumbnailData} with {@link TaskSnapshot} for the given {@param taskId}. * The snapshot will be triggered if no cached {@link TaskSnapshot} exists. */ @@ -247,25 +240,6 @@ public class ActivityManagerWrapper { } /** - * Starts a task from Recents. - * - * @param resultCallback The result success callback - * @param resultCallbackHandler The handler to receive the result callback - */ - public void startActivityFromRecentsAsync(Task.TaskKey taskKey, ActivityOptions options, - Consumer<Boolean> resultCallback, Handler resultCallbackHandler) { - final boolean result = startActivityFromRecents(taskKey, options); - if (resultCallback != null) { - resultCallbackHandler.post(new Runnable() { - @Override - public void run() { - resultCallback.accept(result); - } - }); - } - } - - /** * Starts a task from Recents synchronously. */ public boolean startActivityFromRecents(Task.TaskKey taskKey, ActivityOptions options) { @@ -286,20 +260,6 @@ public class ActivityManagerWrapper { } /** - * @deprecated use {@link TaskStackChangeListeners#registerTaskStackListener} - */ - public void registerTaskStackListener(TaskStackChangeListener listener) { - TaskStackChangeListeners.getInstance().registerTaskStackListener(listener); - } - - /** - * @deprecated use {@link TaskStackChangeListeners#unregisterTaskStackListener} - */ - public void unregisterTaskStackListener(TaskStackChangeListener listener) { - TaskStackChangeListeners.getInstance().unregisterTaskStackListener(listener); - } - - /** * Requests that the system close any open system windows (including other SystemUI). */ public void closeSystemWindows(final String reason) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java index add2d022e893..be99b270c09a 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java @@ -28,14 +28,6 @@ import android.os.Handler; public abstract class ActivityOptionsCompat { /** - * @Deprecated - * @return ActivityOptions for starting a task in split screen as the primary window. - */ - public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft) { - return ActivityOptions.makeBasic(); - } - - /** * @return ActivityOptions for starting a task in freeform. */ public static ActivityOptions makeFreeformOptions() { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java index 630fb360cc14..97e024238778 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java @@ -204,28 +204,6 @@ public class QuickStepContract { } /** - * Touch slopes and thresholds for quick step operations. Drag slop is the point where the - * home button press/long press over are ignored and will start to drag when exceeded and the - * touch slop is when the respected operation will occur when exceeded. Touch slop must be - * larger than the drag slop. - */ - public static int getQuickStepDragSlopPx() { - return convertDpToPixel(10); - } - - public static int getQuickStepTouchSlopPx() { - return convertDpToPixel(24); - } - - public static int getQuickScrubTouchSlopPx() { - return convertDpToPixel(24); - } - - private static int convertDpToPixel(float dp) { - return (int) (dp * Resources.getSystem().getDisplayMetrics().density); - } - - /** * Returns whether the specified sysui state is such that the assistant gesture should be * disabled. */ diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java index a66dc7743792..ff2a7a132288 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java @@ -224,6 +224,7 @@ public class RemoteTransitionCompat implements Parcelable { private WindowContainerToken mRecentsTask = null; private TransitionInfo mInfo = null; private ArrayList<SurfaceControl> mOpeningLeashes = null; + private boolean mOpeningHome = false; private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null; private PictureInPictureSurfaceTransaction mPipTransaction = null; private IBinder mTransition = null; @@ -321,6 +322,7 @@ public class RemoteTransitionCompat implements Parcelable { } final int layer = mInfo.getChanges().size() * 3; mOpeningLeashes = new ArrayList<>(); + mOpeningHome = cancelRecents; final RemoteAnimationTargetCompat[] targets = new RemoteAnimationTargetCompat[openingTasks.size()]; for (int i = 0; i < openingTasks.size(); ++i) { @@ -406,6 +408,26 @@ public class RemoteTransitionCompat implements Parcelable { if (!mKeyguardLocked && mRecentsTask != null) { wct.restoreTransientOrder(mRecentsTask); } + } else if (toHome && mOpeningHome && mPausingTasks != null) { + // Special situaition where 3p launcher was changed during recents (this happens + // during tapltests...). Here we get both "return to home" AND "home opening". + // This is basically going home, but we have to restore recents order and also + // treat the home "pausing" task properly. + for (int i = mPausingTasks.size() - 1; i >= 0; --i) { + final TransitionInfo.Change change = mInfo.getChange(mPausingTasks.get(i)); + final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); + if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { + // Treat as opening (see above) + wct.reorder(mPausingTasks.get(i), true /* onTop */); + t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash()); + } else { + // Treat as hiding (see below) + t.hide(mInfo.getChange(mPausingTasks.get(i)).getLeash()); + } + } + if (!mKeyguardLocked && mRecentsTask != null) { + wct.restoreTransientOrder(mRecentsTask); + } } else { for (int i = 0; i < mPausingTasks.size(); ++i) { if (!sendUserLeaveHint) { @@ -444,6 +466,7 @@ public class RemoteTransitionCompat implements Parcelable { mPausingTasks = null; mInfo = null; mOpeningLeashes = null; + mOpeningHome = false; mLeashMap = null; mTransition = null; } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java deleted file mode 100644 index 359d36939b31..000000000000 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.shared.system; - -import android.content.Intent; -import android.os.Bundle; -import android.view.SurfaceView; - -/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */ -public final class UniversalSmartspaceUtils { - public static final String ACTION_REQUEST_SMARTSPACE_VIEW = - "com.android.systemui.REQUEST_SMARTSPACE_VIEW"; - public static final String INTENT_BUNDLE_KEY = "bundle_key"; - - private static final String SYSUI_PACKAGE = "com.android.systemui"; - - /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */ - public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) { - Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW); - - Bundle bundle = SurfaceViewRequestUtils.createSurfaceBundle(surfaceView); - return intent - .putExtra(INTENT_BUNDLE_KEY, bundle) - .setPackage(SYSUI_PACKAGE) - .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY - | Intent.FLAG_RECEIVER_FOREGROUND); - } - - private UniversalSmartspaceUtils() {} -} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java index b894b10ff073..5577513f4c3c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java @@ -114,30 +114,6 @@ public class WindowManagerWrapper { } /** - * Sets if app requested fixed orientation should be ignored for given displayId. - */ - public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) { - try { - WindowManagerGlobal.getWindowManagerService().setIgnoreOrientationRequest( - displayId, ignoreOrientationRequest); - } catch (RemoteException e) { - Log.e(TAG, "Failed to setIgnoreOrientationRequest()", e); - } - } - - /** - * @return the stable insets for the primary display. - */ - public void getStableInsets(Rect outStableInsets) { - try { - WindowManagerGlobal.getWindowManagerService().getStableInsets(DEFAULT_DISPLAY, - outStableInsets); - } catch (RemoteException e) { - Log.e(TAG, "Failed to get stable insets", e); - } - } - - /** * Overrides a pending app transition. */ public void overridePendingAppTransitionMultiThumbFuture( @@ -153,16 +129,6 @@ public class WindowManagerWrapper { } } - public void overridePendingAppTransitionRemote( - RemoteAnimationAdapterCompat remoteAnimationAdapter, int displayId) { - try { - WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionRemote( - remoteAnimationAdapter.getWrapped(), displayId); - } catch (RemoteException e) { - Log.w(TAG, "Failed to override pending app transition (remote): ", e); - } - } - /** * Enable or disable haptic feedback on the navigation bar buttons. */ @@ -175,19 +141,6 @@ public class WindowManagerWrapper { } } - public void setRecentsVisibility(boolean visible) { - try { - WindowManagerGlobal.getWindowManagerService().setRecentsVisibility(visible); - } catch (RemoteException e) { - Log.w(TAG, "Failed to set recents visibility"); - } - } - - @Deprecated - public void setPipVisibility(final boolean visible) { - // To be removed - } - /** * @param displayId the id of display to check if there is a software navigation bar. * @@ -202,22 +155,6 @@ public class WindowManagerWrapper { } /** - * @return The side of the screen where navigation bar is positioned. - * @see #NAV_BAR_POS_RIGHT - * @see #NAV_BAR_POS_LEFT - * @see #NAV_BAR_POS_BOTTOM - * @see #NAV_BAR_POS_INVALID - */ - public int getNavBarPosition(int displayId) { - try { - return WindowManagerGlobal.getWindowManagerService().getNavBarPosition(displayId); - } catch (RemoteException e) { - Log.w(TAG, "Failed to get nav bar position"); - } - return NAV_BAR_POS_INVALID; - } - - /** * Mirrors a specified display. The SurfaceControl returned is the root of the mirrored * hierarchy. * diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java index 12fa401d7fea..d32219a9817f 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java @@ -336,6 +336,11 @@ public class KeyguardHostViewController extends ViewController<KeyguardHostView> mKeyguardSecurityContainerController.onStartingToHide(); } + /** Called when bouncer visibility changes. */ + public void onBouncerVisibilityChanged(@View.Visibility int visibility) { + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility); + } + public boolean hasDismissActions() { return mDismissAction != null || mCancelAction != null; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt index db2b4ac2c669..58e0fb968204 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt @@ -58,7 +58,6 @@ data class KeyguardFaceListenModel( val keyguardAwake: Boolean, val keyguardGoingAway: Boolean, val listeningForFaceAssistant: Boolean, - val lockIconPressed: Boolean, val occludingAppRequestingFaceAuth: Boolean, val primaryUser: Boolean, val scanningAllowedByStrongAuth: Boolean, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 61e262440607..5ee659be6dd2 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -17,6 +17,7 @@ package com.android.keyguard; import static android.app.StatusBarManager.SESSION_KEYGUARD; +import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC; import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS; @@ -32,11 +33,13 @@ import android.app.admin.DevicePolicyManager; import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.hardware.biometrics.BiometricSourceType; import android.metrics.LogMaker; import android.os.UserHandle; import android.util.Log; import android.util.Slog; import android.view.MotionEvent; +import android.view.View; import androidx.annotation.Nullable; @@ -55,6 +58,7 @@ import com.android.keyguard.dagger.KeyguardBouncerScope; import com.android.settingslib.utils.ThreadUtils; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; +import com.android.systemui.biometrics.SidefpsController; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; @@ -67,6 +71,8 @@ import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.ViewController; import com.android.systemui.util.settings.GlobalSettings; +import java.util.Optional; + import javax.inject.Inject; /** Controller for {@link KeyguardSecurityContainer} */ @@ -93,6 +99,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard private final GlobalSettings mGlobalSettings; private final FeatureFlags mFeatureFlags; private final SessionTracker mSessionTracker; + private final Optional<SidefpsController> mSidefpsController; private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED; @@ -236,13 +243,27 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard reloadColors(); } }; + private boolean mBouncerVisible = false; private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() { - @Override - public void onDevicePolicyManagerStateChanged() { - showPrimarySecurityScreen(false); - } - }; + @Override + public void onDevicePolicyManagerStateChanged() { + showPrimarySecurityScreen(false); + } + + @Override + public void onBiometricRunningStateChanged(boolean running, + BiometricSourceType biometricSourceType) { + if (biometricSourceType == FINGERPRINT) { + updateSideFpsVisibility(); + } + } + + @Override + public void onStrongAuthStateChanged(int userId) { + updateSideFpsVisibility(); + } + }; private KeyguardSecurityContainerController(KeyguardSecurityContainer view, AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory, @@ -260,7 +281,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard UserSwitcherController userSwitcherController, FeatureFlags featureFlags, GlobalSettings globalSettings, - SessionTracker sessionTracker) { + SessionTracker sessionTracker, + Optional<SidefpsController> sidefpsController) { super(view); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = keyguardUpdateMonitor; @@ -280,6 +302,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mFeatureFlags = featureFlags; mGlobalSettings = globalSettings; mSessionTracker = sessionTracker; + mSidefpsController = sidefpsController; } @Override @@ -311,8 +334,23 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard getCurrentSecurityController().onPause(); } mView.onPause(); + // It might happen that onStartingToHide is not called when the device is locked while on + // bouncer. + setBouncerVisible(false); } + private void updateSideFpsVisibility() { + if (!mSidefpsController.isPresent()) { + return; + } + if (mBouncerVisible && mView.isSidedSecurityMode() + && mUpdateMonitor.isFingerprintDetectionRunning() + && !mUpdateMonitor.userNeedsStrongAuth()) { + mSidefpsController.get().show(); + } else { + mSidefpsController.get().hide(); + } + } /** * Shows the primary security screen for the user. This will be either the multi-selector @@ -397,6 +435,17 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard if (mCurrentSecurityMode != SecurityMode.None) { getCurrentSecurityController().onStartingToHide(); } + setBouncerVisible(false); + } + + /** Called when the bouncer changes visibility. */ + public void onBouncerVisibilityChanged(@View.Visibility int visibility) { + setBouncerVisible(visibility == View.VISIBLE); + } + + private void setBouncerVisible(boolean visible) { + mBouncerVisible = visible; + updateSideFpsVisibility(); } /** @@ -655,6 +704,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard private final FeatureFlags mFeatureFlags; private final UserSwitcherController mUserSwitcherController; private final SessionTracker mSessionTracker; + private final Optional<SidefpsController> mSidefpsController; @Inject Factory(KeyguardSecurityContainer view, @@ -673,7 +723,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard UserSwitcherController userSwitcherController, FeatureFlags featureFlags, GlobalSettings globalSettings, - SessionTracker sessionTracker) { + SessionTracker sessionTracker, + Optional<SidefpsController> sidefpsController) { mView = view; mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory; mLockPatternUtils = lockPatternUtils; @@ -690,6 +741,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mGlobalSettings = globalSettings; mUserSwitcherController = userSwitcherController; mSessionTracker = sessionTracker; + mSidefpsController = sidefpsController; } public KeyguardSecurityContainerController create( @@ -699,7 +751,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger, mKeyguardStateController, securityCallback, mSecurityViewFlipperController, mConfigurationController, mFalsingCollector, mFalsingManager, - mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker); + mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker, + mSidefpsController); } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index ede62437e5a0..c19175742ce5 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -41,7 +41,6 @@ import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; import android.app.AlarmManager; -import android.app.PendingIntent; import android.app.UserSwitchObserver; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; @@ -150,11 +149,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final boolean DEBUG_SPEW = false; private static final int BIOMETRIC_LOCKOUT_RESET_DELAY_MS = 600; - private static final String ACTION_FACE_UNLOCK_STARTED - = "com.android.facelock.FACE_UNLOCK_STARTED"; - private static final String ACTION_FACE_UNLOCK_STOPPED - = "com.android.facelock.FACE_UNLOCK_STOPPED"; - // Callback messages private static final int MSG_TIME_UPDATE = 301; private static final int MSG_BATTERY_UPDATE = 302; @@ -165,13 +159,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final int MSG_USER_SWITCHING = 310; private static final int MSG_KEYGUARD_RESET = 312; private static final int MSG_USER_SWITCH_COMPLETE = 314; - private static final int MSG_USER_INFO_CHANGED = 317; private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318; private static final int MSG_STARTED_WAKING_UP = 319; private static final int MSG_FINISHED_GOING_TO_SLEEP = 320; private static final int MSG_STARTED_GOING_TO_SLEEP = 321; private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322; - private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327; private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328; private static final int MSG_AIRPLANE_MODE_CHANGED = 329; private static final int MSG_SERVICE_STATE_CHANGE = 330; @@ -250,7 +242,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final Context mContext; private final boolean mIsPrimaryUser; - private final boolean mIsAutomotive; private final AuthController mAuthController; private final StatusBarStateController mStatusBarStateController; private int mStatusBarState; @@ -328,8 +319,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final LatencyTracker mLatencyTracker; private boolean mLogoutEnabled; private boolean mIsFaceEnrolled; - // If the user long pressed the lock icon, disabling face auth for the current session. - private boolean mLockIconPressed; private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private final Executor mBackgroundExecutor; private SensorPrivacyManager mSensorPrivacyManager; @@ -408,7 +397,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private SparseBooleanArray mUserHasTrust = new SparseBooleanArray(); private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray(); private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray(); - private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray(); private Map<Integer, Intent> mSecondaryLockscreenRequirement = new HashMap<Integer, Intent>(); @VisibleForTesting @@ -1135,21 +1123,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - private void handleFaceUnlockStateChanged(boolean running, int userId) { - Assert.isMainThread(); - mUserFaceUnlockRunning.put(userId, running); - for (int i = 0; i < mCallbacks.size(); i++) { - KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); - if (cb != null) { - cb.onFaceUnlockStateChanged(running, userId); - } - } - } - - public boolean isFaceUnlockRunning(int userId) { - return mUserFaceUnlockRunning.get(userId); - } - public boolean isFingerprintDetectionRunning() { return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING; } @@ -1373,16 +1346,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - static class DisplayClientState { - public int clientGeneration; - public boolean clearing; - public PendingIntent intent; - public int playbackState; - public long playbackEventTime; - } - - private DisplayClientState mDisplayClientState = new DisplayClientState(); - @VisibleForTesting protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @@ -1456,19 +1419,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab final String action = intent.getAction(); if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) { mHandler.sendEmptyMessage(MSG_TIME_UPDATE); - } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED, - intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0)); - } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) { - Trace.beginSection( - "KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive " - + "ACTION_FACE_UNLOCK_STARTED"); - mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1, - getSendingUserId())); - Trace.endSection(); - } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0, - getSendingUserId())); } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED .equals(action)) { mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED, @@ -1767,7 +1717,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab protected void handleStartedGoingToSleep(int arg1) { Assert.isMainThread(); - mLockIconPressed = false; clearBiometricRecognized(); for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); @@ -1815,16 +1764,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - private void handleUserInfoChanged(int userId) { - Assert.isMainThread(); - for (int i = 0; i < mCallbacks.size(); i++) { - KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); - if (cb != null) { - cb.onUserInfoChanged(userId); - } - } - } - private void handleUserUnlocked(int userId) { Assert.isMainThread(); mUserIsUnlocked.put(userId, true); @@ -1942,9 +1881,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab case MSG_KEYGUARD_BOUNCER_CHANGED: handleKeyguardBouncerChanged(msg.arg1, msg.arg2); break; - case MSG_USER_INFO_CHANGED: - handleUserInfoChanged(msg.arg1); - break; case MSG_REPORT_EMERGENCY_CALL_ACTION: handleReportEmergencyCallAction(); break; @@ -1959,12 +1895,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab handleStartedWakingUp(); Trace.endSection(); break; - case MSG_FACE_UNLOCK_STATE_CHANGED: - Trace.beginSection( - "KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED"); - handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2); - Trace.endSection(); - break; case MSG_SIM_SUBSCRIPTION_INFO_CHANGED: handleSimSubscriptionInfoChanged(); break; @@ -2052,24 +1982,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab .getServiceStateForSubscriber(subId); mHandler.sendMessage( mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState)); - - // Get initial state. Relying on Sticky behavior until API for getting info. - if (mBatteryStatus == null) { - Intent intent = mContext.registerReceiver( - null, - new IntentFilter(Intent.ACTION_BATTERY_CHANGED) - ); - if (intent != null && mBatteryStatus == null) { - mBroadcastReceiver.onReceive(mContext, intent); - } - } }); final IntentFilter allUserFilter = new IntentFilter(); - allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED); allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED); - allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED); - allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED); allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); allUserFilter.addAction(ACTION_USER_UNLOCKED); allUserFilter.addAction(ACTION_USER_STOPPED); @@ -2127,8 +2043,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback); } - mIsAutomotive = isAutomotive(); - TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); mUserManager = context.getSystemService(UserManager.class); mIsPrimaryUser = mUserManager.isPrimaryUser(); @@ -2629,7 +2543,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab || mAuthController.isUdfpsFingerDown() || mUdfpsBouncerShowing) && !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer - && !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed + && !mKeyguardGoingAway && biometricEnabledForUser && strongAuthAllowsScanning && mIsPrimaryUser && (!mSecureCameraLaunched || mOccludingAppRequestingFace) && !faceAuthenticated @@ -2652,7 +2566,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab awakeKeyguard, mKeyguardGoingAway, shouldListenForFaceAssistant, - mLockIconPressed, mOccludingAppRequestingFace, mIsPrimaryUser, strongAuthAllowsScanning, @@ -2697,18 +2610,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - /** - * Whenever the lock icon is long pressed, disabling trust agents. - * This means that we cannot auth passively (face) until the user presses power. - */ - public void onLockIconPressed() { - mLockIconPressed = true; - final int userId = getCurrentUser(); - mUserFaceAuthenticated.put(userId, null); - updateFaceListeningState(BIOMETRIC_ACTION_UPDATE); - mStrongAuthTracker.onStrongAuthRequiredChanged(userId); - } - private void startListeningForFingerprint() { final int userId = getCurrentUser(); final boolean unlockPossible = isUnlockWithFingerprintPossible(userId); @@ -3179,20 +3080,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE); } - /** Notifies that the occluded state changed. */ - public void onKeyguardOccludedChanged(boolean occluded) { - Assert.isMainThread(); - if (DEBUG) { - Log.d(TAG, "onKeyguardOccludedChanged(" + occluded + ")"); - } - for (int i = 0; i < mCallbacks.size(); i++) { - KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); - if (cb != null) { - cb.onKeyguardOccludedChanged(occluded); - } - } - } - /** * Handle {@link #MSG_KEYGUARD_RESET} */ @@ -3347,10 +3234,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab return false; } - private boolean isAutomotive() { - return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); - } - /** * Remove the given observer's callback. * @@ -3413,8 +3296,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab callback.onTimeChanged(); callback.onPhoneStateChanged(mPhoneState); callback.onRefreshCarrierInfo(); - callback.onClockVisibilityChanged(); - callback.onKeyguardOccludedChanged(mKeyguardOccluded); callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible); callback.onTelephonyCapable(mTelephonyCapable); @@ -3591,10 +3472,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab || state == TelephonyManager.SIM_STATE_PERM_DISABLED); } - public DisplayClientState getCachedDisplayClientState() { - return mDisplayClientState; - } - // TODO: use these callbacks elsewhere in place of the existing notifyScreen*() // (KeyguardViewMediator, KeyguardHostView) public void dispatchStartedWakingUp() { @@ -3823,9 +3700,5 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab pw.println(" mNeedsSlowUnlockTransition=" + mNeedsSlowUnlockTransition); } mListenModels.print(pw); - - if (mIsAutomotive) { - pw.println(" Running on Automotive build"); - } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 051b81e484d8..99e0ce29a8c2 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -80,12 +80,6 @@ public class KeyguardUpdateMonitorCallback { */ public void onKeyguardVisibilityChanged(boolean showing) { } - /** - * Called when the keyguard occluded state changes. - * @param occluded Indicates if the keyguard is now occluded. - */ - public void onKeyguardOccludedChanged(boolean occluded) { } - public void onKeyguardVisibilityChangedRaw(boolean showing) { final long now = SystemClock.elapsedRealtime(); if (showing == mShowing @@ -117,12 +111,6 @@ public class KeyguardUpdateMonitorCallback { public void onKeyguardDismissAnimationFinished() { } /** - * Called when visibility of lockscreen clock changes, such as when - * obscured by a widget. - */ - public void onClockVisibilityChanged() { } - - /** * Called when the device becomes provisioned */ public void onDeviceProvisioned() { } @@ -151,11 +139,6 @@ public class KeyguardUpdateMonitorCallback { public void onSimStateChanged(int subId, int slotId, int simState) { } /** - * Called when the user's info changed. - */ - public void onUserInfoChanged(int userId) { } - - /** * Called when a user got unlocked. */ public void onUserUnlocked() { } @@ -260,11 +243,6 @@ public class KeyguardUpdateMonitorCallback { BiometricSourceType biometricSourceType) { } /** - * Called when the state of face unlock changed. - */ - public void onFaceUnlockStateChanged(boolean running, int userId) { } - - /** * Called when biometric running state changed. */ public void onBiometricRunningStateChanged(boolean running, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java index ca8728aecb4c..8293c74c5e75 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java @@ -23,10 +23,10 @@ import android.view.ViewRootImpl; import androidx.annotation.Nullable; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; /** diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java index b3c11584bcf8..49e97836b18b 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java @@ -16,6 +16,10 @@ package com.android.keyguard.dagger; +import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor; + +import android.annotation.Nullable; +import android.hardware.fingerprint.FingerprintManager; import android.view.LayoutInflater; import android.view.ViewGroup; @@ -23,9 +27,14 @@ import com.android.keyguard.KeyguardHostView; import com.android.keyguard.KeyguardSecurityContainer; import com.android.keyguard.KeyguardSecurityViewFlipper; import com.android.systemui.R; +import com.android.systemui.biometrics.SidefpsController; import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.statusbar.phone.KeyguardBouncer; +import java.util.Optional; + +import javax.inject.Provider; + import dagger.Module; import dagger.Provides; @@ -60,4 +69,16 @@ public interface KeyguardBouncerModule { KeyguardSecurityContainer containerView) { return containerView.findViewById(R.id.view_flipper); } + + /** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */ + @Provides + @KeyguardBouncerScope + static Optional<SidefpsController> providesOptionalSidefpsController( + @Nullable FingerprintManager fingerprintManager, + Provider<SidefpsController> sidefpsControllerProvider) { + if (!hasSideFpsSensor(fingerprintManager)) { + return Optional.empty(); + } + return Optional.of(sidefpsControllerProvider.get()); + } } diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java index 153da4b6695a..d01c98a934ff 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java @@ -17,9 +17,9 @@ package com.android.keyguard.dagger; import com.android.keyguard.KeyguardStatusViewController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import dagger.BindsInstance; import dagger.Subcomponent; diff --git a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java index b2d5c216dcd1..74d7a8b03b7d 100644 --- a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java +++ b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java @@ -20,6 +20,13 @@ import android.view.MotionEvent; // ACHTUNG! public interface Gefingerpoken { - boolean onInterceptTouchEvent(MotionEvent ev); - boolean onTouchEvent(MotionEvent ev); + /** Called when a touch is being intercepted in a ViewGroup. */ + default boolean onInterceptTouchEvent(MotionEvent ev) { + return false; + } + + /** Called when a touch is being handled by a view. */ + default boolean onTouchEvent(MotionEvent ev) { + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java index 714d267bb07d..527ce127820e 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java @@ -16,160 +16,22 @@ package com.android.systemui; -import android.app.Activity; -import android.app.Application; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.ContentProvider; import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.AppComponentFactory; - -import com.android.systemui.dagger.ContextComponentHelper; -import com.android.systemui.dagger.SysUIComponent; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.inject.Inject; /** - * Implementation of AppComponentFactory that injects into constructors. + * Starts up SystemUI using the AOSP {@link SystemUIInitializerImpl}. * - * This class sets up dependency injection when creating our application. + * This initializer relies on reflection to start everything up and should be considered deprecated. + * Instead, create your own {@link SystemUIAppComponentFactoryBase}, specify it in your + * AndroidManifest.xml and construct your own {@link SystemUIInitializer} directly. * - * Services support dependency injection into their constructors. - * - * ContentProviders support injection into member variables - _not_ constructors. + * @deprecated Define your own SystemUIAppComponentFactoryBase implementation and use that. This + * implementation may be changed or removed in future releases. */ -public class SystemUIAppComponentFactory extends AppComponentFactory { - - private static final String TAG = "AppComponentFactory"; - @Inject - public ContextComponentHelper mComponentHelper; - - public SystemUIAppComponentFactory() { - super(); - } - - @NonNull +@Deprecated +public class SystemUIAppComponentFactory extends SystemUIAppComponentFactoryBase { @Override - public Application instantiateApplicationCompat( - @NonNull ClassLoader cl, @NonNull String className) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - Application app = super.instantiateApplicationCompat(cl, className); - if (app instanceof ContextInitializer) { - ((ContextInitializer) app).setContextAvailableCallback( - context -> { - SystemUIFactory.createFromConfig(context); - SystemUIFactory.getInstance().getSysUIComponent().inject( - SystemUIAppComponentFactory.this); - } - ); - } - - return app; - } - - @NonNull - @Override - public ContentProvider instantiateProviderCompat( - @NonNull ClassLoader cl, @NonNull String className) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - - ContentProvider contentProvider = super.instantiateProviderCompat(cl, className); - if (contentProvider instanceof ContextInitializer) { - ((ContextInitializer) contentProvider).setContextAvailableCallback( - context -> { - SystemUIFactory.createFromConfig(context); - SysUIComponent rootComponent = - SystemUIFactory.getInstance().getSysUIComponent(); - try { - Method injectMethod = rootComponent.getClass() - .getMethod("inject", contentProvider.getClass()); - injectMethod.invoke(rootComponent, contentProvider); - } catch (NoSuchMethodException - | IllegalAccessException - | InvocationTargetException e) { - Log.w(TAG, "No injector for class: " + contentProvider.getClass(), e); - } - } - ); - } - - return contentProvider; - } - - @NonNull - @Override - public Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className, - @Nullable Intent intent) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - if (mComponentHelper == null) { - // This shouldn't happen, but is seen on occasion. - // Bug filed against framework to take a look: http://b/141008541 - SystemUIFactory.getInstance().getSysUIComponent().inject( - SystemUIAppComponentFactory.this); - } - Activity activity = mComponentHelper.resolveActivity(className); - if (activity != null) { - return activity; - } - return super.instantiateActivityCompat(cl, className, intent); - } - - @NonNull - @Override - public Service instantiateServiceCompat( - @NonNull ClassLoader cl, @NonNull String className, Intent intent) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - if (mComponentHelper == null) { - // This shouldn't happen, but does when a device is freshly formatted. - // Bug filed against framework to take a look: http://b/141008541 - SystemUIFactory.getInstance().getSysUIComponent().inject( - SystemUIAppComponentFactory.this); - } - Service service = mComponentHelper.resolveService(className); - if (service != null) { - return service; - } - return super.instantiateServiceCompat(cl, className, intent); - } - - @NonNull - @Override - public BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl, - @NonNull String className, @Nullable Intent intent) - throws InstantiationException, IllegalAccessException, ClassNotFoundException { - if (mComponentHelper == null) { - // This shouldn't happen, but does when a device is freshly formatted. - // Bug filed against framework to take a look: http://b/141008541 - SystemUIFactory.getInstance().getSysUIComponent().inject( - SystemUIAppComponentFactory.this); - } - BroadcastReceiver receiver = mComponentHelper.resolveBroadcastReceiver(className); - if (receiver != null) { - return receiver; - } - - return super.instantiateReceiverCompat(cl, className, intent); - } - - /** - * A callback that receives a Context when one is ready. - */ - public interface ContextAvailableCallback { - void onContextAvailable(Context context); - } - - /** - * Implemented in classes that get started by the system before a context is available. - */ - public interface ContextInitializer { - void setContextAvailableCallback(ContextAvailableCallback callback); + protected SystemUIInitializer createSystemUIInitializer(Context context) { + return SystemUIInitializerFactory.createWithContext(context); } } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt new file mode 100644 index 000000000000..12108b01ab28 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui + +import android.app.Activity +import android.app.Application +import android.app.Service +import android.content.BroadcastReceiver +import android.content.ContentProvider +import android.content.Context +import android.content.Intent +import android.util.Log +import androidx.core.app.AppComponentFactory +import com.android.systemui.dagger.ContextComponentHelper +import java.lang.reflect.InvocationTargetException +import java.util.concurrent.ExecutionException +import javax.inject.Inject + +/** + * Implementation of AppComponentFactory that injects into constructors. + * + * This class sets up dependency injection when creating our application. + * + * Activities, Services, and BroadcastReceivers support dependency injection into + * their constructors. + * + * ContentProviders support injection into member variables - _not_ constructors. + */ +abstract class SystemUIAppComponentFactoryBase : AppComponentFactory() { + companion object { + private const val TAG = "AppComponentFactory" + // Must be static due to http://b/141008541. + var systemUIInitializer: SystemUIInitializer? = null + } + + @set:Inject + lateinit var componentHelper: ContextComponentHelper + + /** + * Returns a new [SystemUIInitializer]. + * + * The returned implementation should be specific to your build. + */ + protected abstract fun createSystemUIInitializer(context: Context): SystemUIInitializer + + private fun createSystemUIInitializerInternal(context: Context): SystemUIInitializer { + return systemUIInitializer ?: run { + val initializer = createSystemUIInitializer(context.applicationContext) + try { + initializer.init(false) + } catch (exception: ExecutionException) { + throw RuntimeException("Failed to initialize SysUI", exception) + } catch (exception: InterruptedException) { + throw RuntimeException("Failed to initialize SysUI", exception) + } + initializer.sysUIComponent.inject( + this@SystemUIAppComponentFactoryBase + ) + + systemUIInitializer = initializer + return initializer + } + } + + override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application { + val app = super.instantiateApplicationCompat(cl, className) + if (app !is ContextInitializer) { + throw RuntimeException("App must implement ContextInitializer") + } else { + app.setContextAvailableCallback { context -> + createSystemUIInitializerInternal(context) + } + } + + return app + } + + override fun instantiateProviderCompat(cl: ClassLoader, className: String): ContentProvider { + val contentProvider = super.instantiateProviderCompat(cl, className) + if (contentProvider is ContextInitializer) { + contentProvider.setContextAvailableCallback { context -> + val initializer = createSystemUIInitializerInternal(context) + val rootComponent = initializer.sysUIComponent + try { + val injectMethod = rootComponent.javaClass + .getMethod("inject", contentProvider.javaClass) + injectMethod.invoke(rootComponent, contentProvider) + } catch (e: NoSuchMethodException) { + Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e) + } catch (e: IllegalAccessException) { + Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e) + } catch (e: InvocationTargetException) { + Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e) + } + initializer + } + } + return contentProvider + } + + override fun instantiateActivityCompat( + cl: ClassLoader, + className: String, + intent: Intent? + ): Activity { + if (!this::componentHelper.isInitialized) { + // This shouldn't happen, but is seen on occasion. + // Bug filed against framework to take a look: http://b/141008541 + systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase) + } + return componentHelper.resolveActivity(className) + ?: super.instantiateActivityCompat(cl, className, intent) + } + + override fun instantiateServiceCompat( + cl: ClassLoader, + className: String, + intent: Intent? + ): Service { + if (!this::componentHelper.isInitialized) { + // This shouldn't happen, but does when a device is freshly formatted. + // Bug filed against framework to take a look: http://b/141008541 + systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase) + } + return componentHelper.resolveService(className) + ?: super.instantiateServiceCompat(cl, className, intent) + } + + override fun instantiateReceiverCompat( + cl: ClassLoader, + className: String, + intent: Intent? + ): BroadcastReceiver { + if (!this::componentHelper.isInitialized) { + // This shouldn't happen, but does when a device is freshly formatted. + // Bug filed against framework to take a look: http://b/141008541 + systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase) + } + return componentHelper.resolveBroadcastReceiver(className) + ?: super.instantiateReceiverCompat(cl, className, intent) + } + + /** + * An Interface for classes that can be notified when an Application Context becomes available. + * + * An instance of this will be passed to implementers of [ContextInitializer]. + */ + fun interface ContextAvailableCallback { + /** Notifies when the Application Context is available. */ + fun onContextAvailable(context: Context): SystemUIInitializer + } + + /** + * Interface for classes that can be constructed by the system before a context is available. + * + * This is intended for [Application] and [ContentProvider] implementations that + * either may not have a Context until some point after construction or are themselves + * a [Context]. + * + * Implementers will be passed a [ContextAvailableCallback] that they should call as soon + * as an Application Context is ready. + */ + interface ContextInitializer { + /** + * Called to supply the [ContextAvailableCallback] that should be called when an + * Application [Context] is available. + */ + fun setContextAvailableCallback(callback: ContextAvailableCallback) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 6d3fd503dff6..9138b2346ab8 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -42,7 +42,6 @@ import android.view.SurfaceControl; import android.view.ThreadedRenderer; import com.android.internal.protolog.common.ProtoLog; -import com.android.systemui.dagger.ContextComponentHelper; import com.android.systemui.dagger.GlobalRootComponent; import com.android.systemui.dagger.SysUIComponent; import com.android.systemui.dump.DumpManager; @@ -65,7 +64,6 @@ public class SystemUIApplication extends Application implements public static final String TAG = "SystemUIService"; private static final boolean DEBUG = false; - private ContextComponentHelper mComponentHelper; private BootCompleteCacheImpl mBootCompleteCache; private DumpManager mDumpManager; @@ -80,8 +78,8 @@ public class SystemUIApplication extends Application implements private CoreStartable[] mServices; private boolean mServicesStarted; private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback; - private GlobalRootComponent mRootComponent; private SysUIComponent mSysUIComponent; + private SystemUIInitializer mInitializer; public SystemUIApplication() { super(); @@ -90,6 +88,10 @@ public class SystemUIApplication extends Application implements ProtoLog.REQUIRE_PROTOLOGTOOL = false; } + protected GlobalRootComponent getRootComponent() { + return mInitializer.getRootComponent(); + } + @Override public void onCreate() { super.onCreate(); @@ -99,10 +101,8 @@ public class SystemUIApplication extends Application implements TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming", Trace.TRACE_TAG_APP); log.traceBegin("DependencyInjection"); - mContextAvailableCallback.onContextAvailable(this); - mRootComponent = SystemUIFactory.getInstance().getRootComponent(); - mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent(); - mComponentHelper = mSysUIComponent.getContextComponentHelper(); + mInitializer = mContextAvailableCallback.onContextAvailable(this); + mSysUIComponent = mInitializer.getSysUIComponent(); mBootCompleteCache = mSysUIComponent.provideBootCacheImpl(); log.traceEnd(); @@ -189,15 +189,14 @@ public class SystemUIApplication extends Application implements */ public void startServicesIfNeeded() { - final String vendorComponent = SystemUIFactory.getInstance() - .getVendorComponent(getResources()); + final String vendorComponent = mInitializer.getVendorComponent(getResources()); // Sort the startables so that we get a deterministic ordering. // TODO: make #start idempotent and require users of CoreStartable to call it. Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>( Comparator.comparing(Class::getName)); - sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents()); - sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser()); + sortedStartables.putAll(mSysUIComponent.getStartables()); + sortedStartables.putAll(mSysUIComponent.getPerUserStartables()); startServicesIfNeeded( sortedStartables, "StartServices", vendorComponent); } @@ -212,7 +211,7 @@ public class SystemUIApplication extends Application implements // Sort the startables so that we get a deterministic ordering. Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>( Comparator.comparing(Class::getName)); - sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser()); + sortedStartables.putAll(mSysUIComponent.getPerUserStartables()); startServicesIfNeeded( sortedStartables, "StartSecondaryServices", null); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java index b05582ee1ec9..08096b03263d 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,95 +11,75 @@ * 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 + * limitations under the License. */ package com.android.systemui; -import android.app.ActivityThread; import android.content.Context; import android.content.res.Resources; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; -import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.dagger.DaggerGlobalRootComponent; import com.android.systemui.dagger.GlobalRootComponent; import com.android.systemui.dagger.SysUIComponent; import com.android.systemui.dagger.WMComponent; -import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider; +import com.android.systemui.util.InitializationChecker; import com.android.wm.shell.dagger.WMShellConcurrencyModule; +import com.android.wm.shell.sysui.ShellInterface; import com.android.wm.shell.transition.ShellTransitions; -import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; - -import javax.inject.Provider; /** - * Class factory to provide customizable SystemUI components. + * Initializer that stands up SystemUI. + * + * Implementations should override {@link #getGlobalRootComponentBuilder()} to fill in their own + * Dagger root component. */ -public class SystemUIFactory { +public abstract class SystemUIInitializer { private static final String TAG = "SystemUIFactory"; - static SystemUIFactory mFactory; + private final Context mContext; + private GlobalRootComponent mRootComponent; private WMComponent mWMComponent; private SysUIComponent mSysUIComponent; - private boolean mInitializeComponents; + private InitializationChecker mInitializationChecker; - public static <T extends SystemUIFactory> T getInstance() { - return (T) mFactory; + public SystemUIInitializer(Context context) { + mContext = context; } - public static void createFromConfig(Context context) { - createFromConfig(context, false); - } - - @VisibleForTesting - public static void createFromConfig(Context context, boolean fromTest) { - if (mFactory != null) { - return; - } + protected abstract GlobalRootComponent.Builder getGlobalRootComponentBuilder(); - final String clsName = context.getString(R.string.config_systemUIFactoryComponent); - if (clsName == null || clsName.length() == 0) { - throw new RuntimeException("No SystemUIFactory component configured"); - } - - try { - Class<?> cls = null; - cls = context.getClassLoader().loadClass(clsName); - mFactory = (SystemUIFactory) cls.newInstance(); - mFactory.init(context, fromTest); - } catch (Throwable t) { - Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t); - throw new RuntimeException(t); - } - } - - @VisibleForTesting - static void cleanup() { - mFactory = null; + /** + * Prepares the SysUIComponent builder before it is built. + * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method + * @param wm the built WMComponent from the root component's getWMComponent() method + */ + protected SysUIComponent.Builder prepareSysUIComponentBuilder( + SysUIComponent.Builder sysUIBuilder, WMComponent wm) { + return sysUIBuilder; } - public SystemUIFactory() {} + /** + * Starts the initialization process. This stands up the Dagger graph. + */ + public void init(boolean fromTest) throws ExecutionException, InterruptedException { + mRootComponent = getGlobalRootComponentBuilder() + .context(mContext) + .instrumentationTest(fromTest) + .build(); - @VisibleForTesting - public void init(Context context, boolean fromTest) - throws ExecutionException, InterruptedException { - // Only initialize components for the main system ui process running as the primary user - mInitializeComponents = !fromTest - && android.os.Process.myUserHandle().isSystem() - && ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName()); - mRootComponent = buildGlobalRootComponent(context); + mInitializationChecker = mRootComponent.getInitializationChecker(); + boolean initializeComponents = mInitializationChecker.initializeComponents(); // Stand up WMComponent - setupWmComponent(context); - if (mInitializeComponents) { + setupWmComponent(mContext); + if (initializeComponents) { // Only initialize when not starting from tests since this currently initializes some // components that shouldn't be run in the test environment mWMComponent.init(); @@ -107,10 +87,11 @@ public class SystemUIFactory { // And finally, retrieve whatever SysUI needs from WMShell and build SysUI. SysUIComponent.Builder builder = mRootComponent.getSysUIComponent(); - if (mInitializeComponents) { + if (initializeComponents) { // Only initialize when not starting from tests since this currently initializes some // components that shouldn't be run in the test environment builder = prepareSysUIComponentBuilder(builder, mWMComponent) + .setShell(mWMComponent.getShell()) .setPip(mWMComponent.getPip()) .setSplitScreen(mWMComponent.getSplitScreen()) .setOneHanded(mWMComponent.getOneHanded()) @@ -130,6 +111,7 @@ public class SystemUIFactory { // TODO: Call on prepareSysUIComponentBuilder but not with real components. Other option // is separating this logic into newly creating SystemUITestsFactory. builder = prepareSysUIComponentBuilder(builder, mWMComponent) + .setShell(new ShellInterface() {}) .setPip(Optional.ofNullable(null)) .setSplitScreen(Optional.ofNullable(null)) .setOneHanded(Optional.ofNullable(null)) @@ -147,7 +129,7 @@ public class SystemUIFactory { .setBackAnimation(Optional.ofNullable(null)); } mSysUIComponent = builder.build(); - if (mInitializeComponents) { + if (initializeComponents) { mSysUIComponent.init(); } @@ -165,7 +147,8 @@ public class SystemUIFactory { */ private void setupWmComponent(Context context) { WMComponent.Builder wmBuilder = mRootComponent.getWMComponentBuilder(); - if (!mInitializeComponents || !WMShellConcurrencyModule.enableShellMainThread(context)) { + if (!mInitializationChecker.initializeComponents() + || !WMShellConcurrencyModule.enableShellMainThread(context)) { // If running under tests or shell thread is not enabled, we don't need anything special mWMComponent = wmBuilder.build(); return; @@ -187,26 +170,6 @@ public class SystemUIFactory { } } - /** - * Prepares the SysUIComponent builder before it is built. - * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method - * @param wm the built WMComponent from the root component's getWMComponent() method - */ - protected SysUIComponent.Builder prepareSysUIComponentBuilder( - SysUIComponent.Builder sysUIBuilder, WMComponent wm) { - return sysUIBuilder; - } - - protected GlobalRootComponent buildGlobalRootComponent(Context context) { - return DaggerGlobalRootComponent.builder() - .context(context) - .build(); - } - - protected boolean shouldInitializeComponents() { - return mInitializeComponents; - } - public GlobalRootComponent getRootComponent() { return mRootComponent; } @@ -220,33 +183,9 @@ public class SystemUIFactory { } /** - * Returns the list of {@link CoreStartable} components that should be started at startup. - */ - public Map<Class<?>, Provider<CoreStartable>> getStartableComponents() { - return mSysUIComponent.getStartables(); - } - - /** * Returns the list of additional system UI components that should be started. */ public String getVendorComponent(Resources resources) { return resources.getString(R.string.config_systemUIVendorServiceComponent); } - - /** - * Returns the list of {@link CoreStartable} components that should be started per user. - */ - public Map<Class<?>, Provider<CoreStartable>> getStartableComponentsPerUser() { - return mSysUIComponent.getPerUserStartables(); - } - - /** - * Creates an instance of ScreenshotNotificationSmartActionsProvider. - * This method is overridden in vendor specific implementation of Sys UI. - */ - public ScreenshotNotificationSmartActionsProvider - createScreenshotNotificationSmartActionsProvider( - Context context, Executor executor, Handler uiHandler) { - return new ScreenshotNotificationSmartActionsProvider(); - } } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt new file mode 100644 index 000000000000..b9454e8c3be8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui + +import android.annotation.SuppressLint +import android.content.Context +import android.util.Log +import com.android.internal.annotations.VisibleForTesting +import com.android.systemui.util.Assert + +/** + * Factory to reflectively lookup a [SystemUIInitializer] to start SystemUI with. + */ +@Deprecated("Provide your own {@link SystemUIAppComponentFactoryBase} that doesn't need this.") +object SystemUIInitializerFactory { + private const val TAG = "SysUIInitializerFactory" + @SuppressLint("StaticFieldLeak") + private var initializer: SystemUIInitializer? = null + + /** + * Instantiate a [SystemUIInitializer] reflectively. + */ + @JvmStatic + fun createWithContext(context: Context): SystemUIInitializer { + return createFromConfig(context) + } + + /** + * Instantiate a [SystemUIInitializer] reflectively. + */ + @JvmStatic + private fun createFromConfig(context: Context): SystemUIInitializer { + Assert.isMainThread() + + return createFromConfigNoAssert(context) + } + + @JvmStatic + @VisibleForTesting + fun createFromConfigNoAssert(context: Context): SystemUIInitializer { + + return initializer ?: run { + val className = context.getString(R.string.config_systemUIFactoryComponent) + if (className.isEmpty()) { + throw RuntimeException("No SystemUIFactory component configured") + } + try { + val cls = context.classLoader.loadClass(className) + val constructor = cls.getConstructor(Context::class.java) + (constructor.newInstance(context) as SystemUIInitializer).apply { + initializer = this + } + } catch (t: Throwable) { + Log.w(TAG, "Error creating SystemUIInitializer component: $className", t) + throw t + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt new file mode 100644 index 000000000000..8920c928da09 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui + +import android.content.Context +import com.android.systemui.dagger.DaggerGlobalRootComponent +import com.android.systemui.dagger.GlobalRootComponent + +/** + * {@link SystemUIInitializer} that stands up AOSP SystemUI. + */ +class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) { + override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder { + return DaggerGlobalRootComponent.builder() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index c9cc3e29f68e..84e1c3d4c8f0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -249,13 +249,13 @@ public class AuthContainerView extends LinearLayout break; case AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN: mFailedModalities.clear(); - mConfig.mCallback.onTryAgainPressed(); + mConfig.mCallback.onTryAgainPressed(getRequestId()); break; case AuthBiometricView.Callback.ACTION_ERROR: animateAway(AuthDialogCallback.DISMISSED_ERROR); break; case AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL: - mConfig.mCallback.onDeviceCredentialPressed(); + mConfig.mCallback.onDeviceCredentialPressed(getRequestId()); mHandler.postDelayed(() -> { addCredentialView(false /* animatePanel */, true /* animateContents */); }, mConfig.mSkipAnimation ? 0 : AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS); @@ -373,7 +373,7 @@ public class AuthContainerView extends LinearLayout void sendEarlyUserCanceled() { mConfig.mCallback.onSystemEvent( - BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL); + BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL, getRequestId()); } @Override @@ -774,7 +774,8 @@ public class AuthContainerView extends LinearLayout private void sendPendingCallbackIfNotNull() { Log.d(TAG, "pendingCallback: " + mPendingCallbackReason); if (mPendingCallbackReason != null) { - mConfig.mCallback.onDismissed(mPendingCallbackReason, mCredentialAttestation); + mConfig.mCallback.onDismissed(mPendingCallbackReason, + mCredentialAttestation, getRequestId()); mPendingCallbackReason = null; } } @@ -804,7 +805,7 @@ public class AuthContainerView extends LinearLayout } mContainerState = STATE_SHOWING; if (mBiometricView != null) { - mConfig.mCallback.onDialogAnimatedIn(); + mConfig.mCallback.onDialogAnimatedIn(getRequestId()); mBiometricView.onDialogAnimatedIn(); } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index a097c5e76149..47ff59cfc281 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -340,11 +340,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } @Override - public void onTryAgainPressed() { + public void onTryAgainPressed(long requestId) { if (mReceiver == null) { Log.e(TAG, "onTryAgainPressed: Receiver is null"); return; } + + if (requestId != mCurrentDialog.getRequestId()) { + Log.w(TAG, "requestId doesn't match, skip onTryAgainPressed"); + return; + } + try { mReceiver.onTryAgainPressed(); } catch (RemoteException e) { @@ -353,11 +359,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } @Override - public void onDeviceCredentialPressed() { + public void onDeviceCredentialPressed(long requestId) { if (mReceiver == null) { Log.e(TAG, "onDeviceCredentialPressed: Receiver is null"); return; } + + if (requestId != mCurrentDialog.getRequestId()) { + Log.w(TAG, "requestId doesn't match, skip onDeviceCredentialPressed"); + return; + } + try { mReceiver.onDeviceCredentialPressed(); } catch (RemoteException e) { @@ -366,11 +378,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } @Override - public void onSystemEvent(int event) { + public void onSystemEvent(int event, long requestId) { if (mReceiver == null) { Log.e(TAG, "onSystemEvent(" + event + "): Receiver is null"); return; } + + if (requestId != mCurrentDialog.getRequestId()) { + Log.w(TAG, "requestId doesn't match, skip onSystemEvent"); + return; + } + try { mReceiver.onSystemEvent(event); } catch (RemoteException e) { @@ -379,12 +397,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } @Override - public void onDialogAnimatedIn() { + public void onDialogAnimatedIn(long requestId) { if (mReceiver == null) { Log.e(TAG, "onDialogAnimatedIn: Receiver is null"); return; } + if (requestId != mCurrentDialog.getRequestId()) { + Log.w(TAG, "requestId doesn't match, skip onDialogAnimatedIn"); + return; + } + try { mReceiver.onDialogAnimatedIn(); } catch (RemoteException e) { @@ -393,7 +416,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba } @Override - public void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation) { + public void onDismissed(@DismissedReason int reason, + @Nullable byte[] credentialAttestation, long requestId) { + + if (mCurrentDialog != null && requestId != mCurrentDialog.getRequestId()) { + Log.w(TAG, "requestId doesn't match, skip onDismissed"); + return; + } + switch (reason) { case AuthDialogCallback.DISMISSED_USER_CANCELED: sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_USER_CANCEL, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java index a7d2901b21c3..bbe461aaf6d9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java @@ -47,27 +47,28 @@ public interface AuthDialogCallback { * @param reason * @param credentialAttestation the HAT received from LockSettingsService upon verification */ - void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation); + void onDismissed(@DismissedReason int reason, + @Nullable byte[] credentialAttestation, long requestId); /** * Invoked when the "try again" button is clicked */ - void onTryAgainPressed(); + void onTryAgainPressed(long requestId); /** * Invoked when the "use password" button is clicked */ - void onDeviceCredentialPressed(); + void onDeviceCredentialPressed(long requestId); /** * See {@link android.hardware.biometrics.BiometricPrompt.Builder * #setReceiveSystemEvents(boolean)} * @param event */ - void onSystemEvent(int event); + void onSystemEvent(int event, long requestId); /** * Notifies when the dialog has finished animating. */ - void onDialogAnimatedIn(); + void onDialogAnimatedIn(long requestId); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt index 04e2dccda528..bbffb73b7503 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt @@ -34,16 +34,16 @@ import android.hardware.fingerprint.ISidefpsController import android.os.Handler import android.util.Log import android.util.RotationUtils -import android.view.View.AccessibilityDelegate -import android.view.accessibility.AccessibilityEvent import android.view.Display import android.view.Gravity import android.view.LayoutInflater import android.view.Surface import android.view.View +import android.view.View.AccessibilityDelegate import android.view.ViewPropertyAnimator import android.view.WindowInsets import android.view.WindowManager +import android.view.accessibility.AccessibilityEvent import androidx.annotation.RawRes import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieProperty @@ -70,13 +70,12 @@ class SidefpsController @Inject constructor( private val activityTaskManager: ActivityTaskManager, overviewProxyService: OverviewProxyService, displayManager: DisplayManager, - @Main mainExecutor: DelayableExecutor, + @Main private val mainExecutor: DelayableExecutor, @Main private val handler: Handler ) { @VisibleForTesting val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager - ?.sensorPropertiesInternal - ?.firstOrNull { it.isAnySidefpsType } + ?.sideFpsSensorProperties ?: throw IllegalStateException("no side fingerprint sensor") @VisibleForTesting @@ -135,25 +134,34 @@ class SidefpsController @Inject constructor( } init { - fingerprintManager?.setSidefpsController(object : ISidefpsController.Stub() { - override fun show( - sensorId: Int, - @BiometricOverlayConstants.ShowReason reason: Int - ) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId) - - private fun doShow() = mainExecutor.execute { - if (overlayView == null) { - createOverlayForDisplay() - } else { - Log.v(TAG, "overlay already shown") - } - } + fingerprintManager?.setSidefpsController( + object : ISidefpsController.Stub() { + override fun show( + sensorId: Int, + @BiometricOverlayConstants.ShowReason reason: Int + ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide() - override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null } - }) + override fun hide(sensorId: Int) = hide() + }) overviewProxyService.addCallback(overviewProxyListener) } + /** Shows the side fps overlay if not already shown. */ + fun show() { + mainExecutor.execute { + if (overlayView == null) { + createOverlayForDisplay() + } else { + Log.v(TAG, "overlay already shown") + } + } + } + + /** Hides the fps overlay if shown. */ + fun hide() { + mainExecutor.execute { overlayView = null } + } + private fun onOrientationChanged() { if (overlayView != null) { createOverlayForDisplay() @@ -266,6 +274,12 @@ class SidefpsController @Inject constructor( } } +private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal? + get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType } + +/** Returns [True] when the device has a side fingerprint sensor. */ +fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null + @BiometricOverlayConstants.ShowReason private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) { REASON_AUTH_KEYGUARD -> false diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java index 4f55ba496b6b..9e33ee1faab3 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java @@ -18,6 +18,9 @@ package com.android.systemui.dagger; import android.content.Context; +import com.android.systemui.dagger.qualifiers.InstrumentationTest; +import com.android.systemui.util.InitializationChecker; + import javax.inject.Singleton; import dagger.BindsInstance; @@ -37,7 +40,8 @@ public interface GlobalRootComponent { interface Builder { @BindsInstance Builder context(Context context); - + @BindsInstance + Builder instrumentationTest(@InstrumentationTest boolean test); GlobalRootComponent build(); } @@ -50,4 +54,9 @@ public interface GlobalRootComponent { * Builder for a {@link SysUIComponent}, which makes it a subcomponent of this class. */ SysUIComponent.Builder getSysUIComponent(); + + /** + * Returns an {@link InitializationChecker}. + */ + InitializationChecker getInitializationChecker(); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java index c4fca60d4b44..2c1463d285f6 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java @@ -44,6 +44,7 @@ import com.android.systemui.qs.dagger.QSModule; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsImplementation; +import com.android.systemui.screenshot.ReferenceScreenshotModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; @@ -99,6 +100,7 @@ import dagger.Provides; MediaModule.class, PowerModule.class, QSModule.class, + ReferenceScreenshotModule.class, StartCentralSurfacesModule.class, VolumeModule.class }) diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index 3a1b12955647..adeafd5fa347 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -21,7 +21,7 @@ import com.android.systemui.BootCompleteCacheImpl; import com.android.systemui.CoreStartable; import com.android.systemui.Dependency; import com.android.systemui.InitController; -import com.android.systemui.SystemUIAppComponentFactory; +import com.android.systemui.SystemUIAppComponentFactoryBase; import com.android.systemui.dagger.qualifiers.PerUser; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; @@ -50,6 +50,7 @@ import com.android.wm.shell.pip.Pip; import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.startingsurface.StartingSurface; +import com.android.wm.shell.sysui.ShellInterface; import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.transition.ShellTransitions; @@ -81,6 +82,9 @@ public interface SysUIComponent { @Subcomponent.Builder interface Builder { @BindsInstance + Builder setShell(ShellInterface s); + + @BindsInstance Builder setPip(Optional<Pip> p); @BindsInstance @@ -241,7 +245,7 @@ public interface SysUIComponent { /** * Member injection into the supplied argument. */ - void inject(SystemUIAppComponentFactory factory); + void inject(SystemUIAppComponentFactoryBase factory); /** * Member injection into the supplied argument. diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index a9f340854689..6db3e82a77b0 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -33,6 +33,7 @@ import com.android.systemui.log.SessionTracker import com.android.systemui.media.RingtonePlayer import com.android.systemui.power.PowerUI import com.android.systemui.recents.Recents +import com.android.systemui.settings.dagger.MultiUserUtilsModule import com.android.systemui.shortcut.ShortcutKeyDispatcher import com.android.systemui.statusbar.notification.InstantAppNotifier import com.android.systemui.statusbar.phone.KeyguardLiftController @@ -51,7 +52,7 @@ import dagger.multibindings.IntoMap /** * Collection of {@link CoreStartable}s that should be run on AOSP. */ -@Module +@Module(includes = [MultiUserUtilsModule::class]) abstract class SystemUICoreStartableModule { /** Inject into AuthController. */ @Binds @@ -205,4 +206,4 @@ abstract class SystemUICoreStartableModule { @IntoMap @ClassKey(KeyguardLiftController::class) abstract fun bindKeyguardLiftController(sysui: KeyguardLiftController): CoreStartable -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 137e28888728..0e0073a1690f 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -26,7 +26,6 @@ import com.android.keyguard.clock.ClockModule; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.BootCompleteCache; import com.android.systemui.BootCompleteCacheImpl; -import com.android.systemui.SystemUIFactory; import com.android.systemui.appops.dagger.AppOpsModule; import com.android.systemui.assist.AssistModule; import com.android.systemui.biometrics.AlternateUdfpsTouchProvider; @@ -50,7 +49,7 @@ import com.android.systemui.plugins.BcSmartspaceDataPlugin; import com.android.systemui.privacy.PrivacyModule; import com.android.systemui.recents.Recents; import com.android.systemui.screenshot.dagger.ScreenshotModule; -import com.android.systemui.settings.dagger.SettingsModule; +import com.android.systemui.settings.dagger.MultiUserUtilsModule; import com.android.systemui.smartspace.dagger.SmartspaceModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -82,6 +81,7 @@ import com.android.systemui.unfold.SysUIUnfoldModule; import com.android.systemui.user.UserModule; import com.android.systemui.util.concurrency.SysUIConcurrencyModule; import com.android.systemui.util.dagger.UtilModule; +import com.android.systemui.util.kotlin.CoroutinesModule; import com.android.systemui.util.sensors.SensorModule; import com.android.systemui.util.settings.SettingsUtilModule; import com.android.systemui.util.time.SystemClock; @@ -90,6 +90,7 @@ import com.android.systemui.wallet.dagger.WalletModule; import com.android.systemui.wmshell.BubblesManager; import com.android.wm.shell.bubbles.Bubbles; import com.android.wm.shell.dagger.DynamicOverride; +import com.android.wm.shell.sysui.ShellController; import java.util.Optional; import java.util.concurrent.Executor; @@ -114,6 +115,7 @@ import dagger.Provides; AssistModule.class, BiometricsModule.class, ClockModule.class, + CoroutinesModule.class, DreamModule.class, ControlsModule.class, DemoModeModule.class, @@ -127,7 +129,7 @@ import dagger.Provides; QsFrameTranslateModule.class, ScreenshotModule.class, SensorModule.class, - SettingsModule.class, + MultiUserUtilsModule.class, SettingsUtilModule.class, SmartRepliesInflationModule.class, SmartspaceModule.class, @@ -198,11 +200,6 @@ public abstract class SystemUIModule { @Binds abstract SystemClock bindSystemClock(SystemClockImpl systemClock); - @Provides - static SystemUIFactory getSystemUIFactory() { - return SystemUIFactory.getInstance(); - } - // TODO: This should provided by the WM component /** Provides Optional of BubbleManager */ @SysUISingleton @@ -212,7 +209,6 @@ public abstract class SystemUIModule { NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, ShadeController shadeController, - ConfigurationController configurationController, @Nullable IStatusBarService statusBarService, INotificationManager notificationManager, NotificationVisibilityProvider visibilityProvider, @@ -230,7 +226,6 @@ public abstract class SystemUIModule { notificationShadeWindowController, keyguardStateController, shadeController, - configurationController, statusBarService, notificationManager, visibilityProvider, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java index 1570a7ebc0c4..b6003e91eeba 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java @@ -21,7 +21,7 @@ import android.os.HandlerThread; import androidx.annotation.Nullable; -import com.android.systemui.SystemUIFactory; +import com.android.systemui.SystemUIInitializerFactory; import com.android.systemui.tv.TvWMComponent; import com.android.wm.shell.ShellCommandHandler; import com.android.wm.shell.ShellInit; @@ -41,6 +41,7 @@ import com.android.wm.shell.pip.Pip; import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.startingsurface.StartingSurface; +import com.android.wm.shell.sysui.ShellInterface; import com.android.wm.shell.tasksurfacehelper.TaskSurfaceHelper; import com.android.wm.shell.transition.ShellTransitions; @@ -52,7 +53,7 @@ import dagger.Subcomponent; /** * Dagger Subcomponent for WindowManager. This class explicitly describes the interfaces exported * from the WM component into the SysUI component (in - * {@link SystemUIFactory#init(Context, boolean)}), and references the specific dependencies + * {@link SystemUIInitializerFactory#init(Context, boolean)}), and references the specific dependencies * provided by its particular device/form-factor SystemUI implementation. * * ie. {@link WMComponent} includes {@link WMShellModule} @@ -88,6 +89,9 @@ public interface WMComponent { Optional<ShellCommandHandler> getShellCommandHandler(); @WMSingleton + ShellInterface getShell(); + + @WMSingleton Optional<OneHanded> getOneHanded(); @WMSingleton diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/InstrumentationTest.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/InstrumentationTest.java new file mode 100644 index 000000000000..a803a39f114f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/InstrumentationTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dagger.qualifiers; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + + +/** + * An annotation for injecting whether or not we are running in a test environment. + */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface InstrumentationTest { +} diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 70e4fa3aa27f..7c816cec08f2 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -26,8 +26,6 @@ import android.os.SystemClock; import android.text.format.Formatter; import android.util.Log; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -44,8 +42,6 @@ import javax.inject.Inject; */ @DozeScope public class DozeUi implements DozeMachine.Part { - // if enabled, calls dozeTimeTick() whenever the time changes: - private static final boolean BURN_IN_TESTING_ENABLED = false; private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min private final Context mContext; private final DozeHost mHost; @@ -57,26 +53,13 @@ public class DozeUi implements DozeMachine.Part { private final DozeParameters mDozeParameters; private final DozeLog mDozeLog; private final StatusBarStateController mStatusBarStateController; - private final KeyguardUpdateMonitorCallback mKeyguardVisibilityCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onTimeChanged() { - if (BURN_IN_TESTING_ENABLED && mStatusBarStateController.isDozing()) { - // update whenever the time changes for manual burn in testing - mHost.dozeTimeTick(); - - // Keep wakelock until a frame has been pushed. - mHandler.post(mWakeLock.wrap(() -> {})); - } - } - }; private long mLastTimeTickElapsed = 0; @Inject public DozeUi(Context context, AlarmManager alarmManager, WakeLock wakeLock, DozeHost host, @Main Handler handler, - DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor, + DozeParameters params, StatusBarStateController statusBarStateController, DozeLog dozeLog) { mContext = context; @@ -86,7 +69,6 @@ public class DozeUi implements DozeMachine.Part { mCanAnimateTransition = !params.getDisplayNeedsBlanking(); mDozeParameters = params; mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler); - keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback); mDozeLog = dozeLog; mStatusBarStateController = statusBarStateController; } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java index 59a17bad5069..a25257d6cf42 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java @@ -43,6 +43,8 @@ public class DreamOverlayStatusBarView extends ConstraintLayout { STATUS_ICON_NOTIFICATIONS, STATUS_ICON_WIFI_UNAVAILABLE, STATUS_ICON_ALARM_SET, + STATUS_ICON_CAMERA_DISABLED, + STATUS_ICON_MIC_DISABLED, STATUS_ICON_MIC_CAMERA_DISABLED, STATUS_ICON_PRIORITY_MODE_ON }) @@ -50,8 +52,10 @@ public class DreamOverlayStatusBarView extends ConstraintLayout { public static final int STATUS_ICON_NOTIFICATIONS = 0; public static final int STATUS_ICON_WIFI_UNAVAILABLE = 1; public static final int STATUS_ICON_ALARM_SET = 2; - public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 3; - public static final int STATUS_ICON_PRIORITY_MODE_ON = 4; + public static final int STATUS_ICON_CAMERA_DISABLED = 3; + public static final int STATUS_ICON_MIC_DISABLED = 4; + public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 5; + public static final int STATUS_ICON_PRIORITY_MODE_ON = 6; private final Map<Integer, View> mStatusIcons = new HashMap<>(); @@ -80,6 +84,10 @@ public class DreamOverlayStatusBarView extends ConstraintLayout { fetchStatusIconForResId(R.id.dream_overlay_wifi_status)); mStatusIcons.put(STATUS_ICON_ALARM_SET, fetchStatusIconForResId(R.id.dream_overlay_alarm_set)); + mStatusIcons.put(STATUS_ICON_CAMERA_DISABLED, + fetchStatusIconForResId(R.id.dream_overlay_camera_off)); + mStatusIcons.put(STATUS_ICON_MIC_DISABLED, + fetchStatusIconForResId(R.id.dream_overlay_mic_off)); mStatusIcons.put(STATUS_ICON_MIC_CAMERA_DISABLED, fetchStatusIconForResId(R.id.dream_overlay_camera_mic_off)); mStatusIcons.put(STATUS_ICON_NOTIFICATIONS, diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java index 250313d0aae8..de7bf28c01d6 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java @@ -214,9 +214,17 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve .isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE); final boolean cameraBlocked = mSensorPrivacyController .isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA); - showIcon( - DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, - micBlocked && cameraBlocked); + @DreamOverlayStatusBarView.StatusIconType int iconType = Resources.ID_NULL; + if (micBlocked && cameraBlocked) { + iconType = DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED; + } else if (!micBlocked && cameraBlocked) { + iconType = DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED; + } else if (micBlocked && !cameraBlocked) { + iconType = DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED; + } + if (iconType != Resources.ID_NULL) { + showIcon(iconType, true); + } } private String buildNotificationsContentDescription(int notificationCount) { diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java index 4eae3b928c64..ce61b163dd17 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java @@ -24,6 +24,7 @@ import android.app.smartspace.SmartspaceAction; import android.app.smartspace.SmartspaceTarget; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.text.TextUtils; @@ -133,16 +134,19 @@ public class DreamWeatherComplication implements Complication { private final ActivityStarter mActivityStarter; private final String mSmartspaceTrampolineActivityComponent; private SmartspaceTargetListener mSmartspaceTargetListener; + private final Resources mResources; @Inject DreamWeatherViewController( @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view, @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline, ActivityStarter activityStarter, - DreamSmartspaceController smartspaceController + DreamSmartspaceController smartspaceController, + Resources resources ) { super(view); mActivityStarter = activityStarter; + mResources = resources; mSmartSpaceController = smartspaceController; mSmartspaceTrampolineActivityComponent = smartspaceTrampoline; } @@ -161,8 +165,10 @@ public class DreamWeatherComplication implements Complication { return; } - String temperature = headerAction.getTitle().toString(); + final CharSequence temperature = headerAction.getTitle(); mView.setText(temperature); + mView.setContentDescription(getFormattedContentDescription(temperature, + headerAction.getContentDescription())); final Icon icon = headerAction.getIcon(); if (icon != null) { final int iconSize = @@ -174,7 +180,6 @@ public class DreamWeatherComplication implements Complication { mView.setCompoundDrawablePadding( getResources().getDimensionPixelSize( R.dimen.smart_action_button_icon_padding)); - } mView.setOnClickListener(v -> { final Intent intent = headerAction.getIntent(); @@ -196,5 +201,21 @@ public class DreamWeatherComplication implements Complication { protected void onViewDetached() { mSmartSpaceController.removeUnfilteredListener(mSmartspaceTargetListener); } + + /** + * Returns a formatted content description for accessibility of the weather condition and + * temperature. + */ + private CharSequence getFormattedContentDescription(CharSequence temperature, + CharSequence weatherCondition) { + if (TextUtils.isEmpty(temperature)) { + return weatherCondition; + } else if (TextUtils.isEmpty(weatherCondition)) { + return temperature; + } + + return mResources.getString(R.string.dream_overlay_weather_complication_desc, + weatherCondition, temperature); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java index 7ab3ad1a621a..f1a16897fdbc 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java @@ -19,12 +19,14 @@ package com.android.systemui.dreams.complication.dagger; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import android.content.res.Resources; import android.view.LayoutInflater; import android.view.ViewGroup; import android.widget.TextView; import com.android.internal.util.Preconditions; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.complication.ComplicationLayoutParams; import com.android.systemui.dreams.complication.DreamWeatherComplication.DreamWeatherViewHolder; @@ -34,6 +36,7 @@ import java.lang.annotation.Retention; import javax.inject.Named; import javax.inject.Scope; +import dagger.Binds; import dagger.Module; import dagger.Provides; import dagger.Subcomponent; @@ -106,5 +109,12 @@ public interface DreamWeatherComplicationComponent { ComplicationLayoutParams.DIRECTION_END, INSERT_ORDER_WEIGHT, /* snapToGuide= */ true); } + + /** + * Binds resources in the dream weather complication scope. + */ + @Binds + @DreamWeatherComplicationScope + Resources getResources(@Main Resources resources); } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java index d0ac1c059eb1..245ea219ea68 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java @@ -199,7 +199,8 @@ public class Flags { public static final SysPropBooleanFlag WM_ALWAYS_ENFORCE_PREDICTIVE_BACK = new SysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", false); - public static final BooleanFlag NEW_BACK_AFFORDANCE = new BooleanFlag(1203, true); + public static final BooleanFlag NEW_BACK_AFFORDANCE = + new BooleanFlag(1203, false /* default */, true /* teamfood */); // Pay no attention to the reflection behind the curtain. // ========================== Curtain ========================== diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 3c88e4023960..e913d2b86306 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -122,6 +122,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.dagger.KeyguardModule; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationShadeDepthController; @@ -131,7 +132,6 @@ import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -556,15 +556,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } @Override - public void onUserInfoChanged(int userId) { - } - - @Override - public void onClockVisibilityChanged() { - adjustStatusBarLocked(); - } - - @Override public void onDeviceProvisioned() { sendUserPresentBroadcast(); synchronized (KeyguardViewMediator.this) { @@ -1197,6 +1188,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, mSystemReady = true; doKeyguardLocked(null); mUpdateMonitor.registerCallback(mUpdateCallback); + adjustStatusBarLocked(); mDreamOverlayStateController.addCallback(mDreamOverlayStateCallback); } // Most services aren't available until the system reaches the ready state, so we diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt new file mode 100644 index 000000000000..55c7ac9fb0cc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt @@ -0,0 +1,114 @@ +package com.android.systemui.lifecycle + +import android.view.View +import android.view.ViewTreeObserver +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LifecycleRegistry + +/** + * [LifecycleOwner] for Window-added Views. + * + * These are [View] instances that are added to a `Window` using the `WindowManager` API. + * + * This implementation goes to: + * * The <b>CREATED</b> `Lifecycle.State` when the view gets attached to the window but the window + * is not yet visible + * * The <b>STARTED</b> `Lifecycle.State` when the view is attached to the window and the window is + * visible + * * The <b>RESUMED</b> `Lifecycle.State` when the view is attached to the window and the window is + * visible and the window receives focus + * + * In table format: + * ``` + * | ----------------------------------------------------------------------------- | + * | View attached to window | Window visible | Window has focus | Lifecycle state | + * | ----------------------------------------------------------------------------- | + * | not attached | Any | INITIALIZED | + * | ----------------------------------------------------------------------------- | + * | | not visible | Any | CREATED | + * | ----------------------------------------------------- | + * | attached | | not focused | STARTED | + * | | is visible |----------------------------------- | + * | | | has focus | RESUMED | + * | ----------------------------------------------------------------------------- | + * ``` + * ### Notes + * * [dispose] must be invoked when the [LifecycleOwner] is done and won't be reused + * * It is always better for [LifecycleOwner] implementations to be more explicit than just + * listening to the state of the `Window`. E.g. if the code that added the `View` to the `Window` + * already has access to the correct state to know when that `View` should become visible and when + * it is ready to receive interaction from the user then it already knows when to move to `STARTED` + * and `RESUMED`, respectively. In that case, it's better to implement your own `LifecycleOwner` + * instead of relying on the `Window` callbacks. + */ +class WindowAddedViewLifecycleOwner +@JvmOverloads +constructor( + private val view: View, + registryFactory: (LifecycleOwner) -> LifecycleRegistry = { LifecycleRegistry(it) }, +) : LifecycleOwner { + + private val windowAttachListener = + object : ViewTreeObserver.OnWindowAttachListener { + override fun onWindowAttached() { + updateCurrentState() + } + + override fun onWindowDetached() { + updateCurrentState() + } + } + private val windowFocusListener = + ViewTreeObserver.OnWindowFocusChangeListener { updateCurrentState() } + private val windowVisibilityListener = + ViewTreeObserver.OnWindowVisibilityChangeListener { updateCurrentState() } + + private val registry = registryFactory(this) + + init { + setCurrentState(Lifecycle.State.INITIALIZED) + + with(view.viewTreeObserver) { + addOnWindowAttachListener(windowAttachListener) + addOnWindowVisibilityChangeListener(windowVisibilityListener) + addOnWindowFocusChangeListener(windowFocusListener) + } + + updateCurrentState() + } + + override fun getLifecycle(): Lifecycle { + return registry + } + + /** + * Disposes of this [LifecycleOwner], performing proper clean-up. + * + * <p>Invoke this when the instance is finished and won't be reused. + */ + fun dispose() { + with(view.viewTreeObserver) { + removeOnWindowAttachListener(windowAttachListener) + removeOnWindowVisibilityChangeListener(windowVisibilityListener) + removeOnWindowFocusChangeListener(windowFocusListener) + } + } + + private fun updateCurrentState() { + val state = + when { + !view.isAttachedToWindow -> Lifecycle.State.INITIALIZED + view.windowVisibility != View.VISIBLE -> Lifecycle.State.CREATED + !view.hasWindowFocus() -> Lifecycle.State.STARTED + else -> Lifecycle.State.RESUMED + } + setCurrentState(state) + } + + private fun setCurrentState(state: Lifecycle.State) { + if (registry.currentState != state) { + registry.currentState = state + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java index ec4c4e6b3363..e9b6af44ddf3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -60,7 +60,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { @Override public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) { final int size = mController.getMediaDevices().size(); - if (position == size && mController.isZeroMode()) { + if (position == size) { viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */, true /* bottomMargin */); } else if (position < size) { @@ -75,7 +75,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { @Override public long getItemId(int position) { final int size = mController.getMediaDevices().size(); - if (position == size && mController.isZeroMode()) { + if (position == size) { return -1; } else if (position < size) { return ((List<MediaDevice>) (mController.getMediaDevices())) @@ -88,11 +88,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { @Override public int getItemCount() { - if (mController.isZeroMode()) { - // Add extra one for "pair new" or dynamic group - return mController.getMediaDevices().size() + 1; - } - return mController.getMediaDevices().size(); + // Add extra one for "pair new" + return mController.getMediaDevices().size() + 1; } class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder { diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index e5913061ef3f..0d5cab688d72 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -91,6 +91,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements private TextView mHeaderSubtitle; private ImageView mHeaderIcon; private ImageView mAppResourceIcon; + private ImageView mBroadcastIcon; private RecyclerView mDevicesRecyclerView; private LinearLayout mDeviceListLayout; private LinearLayout mCastAppLayout; @@ -239,6 +240,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements mAppButton = mDialogView.requireViewById(R.id.launch_app_button); mAppResourceIcon = mDialogView.requireViewById(R.id.app_source_icon); mCastAppLayout = mDialogView.requireViewById(R.id.cast_app_section); + mBroadcastIcon = mDialogView.requireViewById(R.id.broadcast_icon); mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener( mDeviceListLayoutListener); @@ -366,6 +368,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements mStopButton.setEnabled(true); mStopButton.setText(getStopButtonText()); mStopButton.setOnClickListener(v -> onStopButtonClick()); + + mBroadcastIcon.setVisibility(getBroadcastIconVisibility()); + mBroadcastIcon.setOnClickListener(v -> onBroadcastIconClick()); } private void updateButtonBackgroundColorFilter() { @@ -490,6 +495,14 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements dismiss(); } + public int getBroadcastIconVisibility() { + return View.GONE; + } + + public void onBroadcastIconClick() { + // Do nothing. + } + public boolean isBroadcastSupported() { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 247ffa7c2ef9..7e3275da8c31 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -16,7 +16,7 @@ package com.android.systemui.media.dialog; -import static android.provider.Settings.ACTION_BLUETOOTH_PAIRING_SETTINGS; +import static android.provider.Settings.ACTION_BLUETOOTH_SETTINGS; import android.annotation.CallbackExecutor; import android.app.AlertDialog; @@ -300,6 +300,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return; } try { + synchronized (mMediaDevicesLock) { + mMediaDevices.removeIf(MediaDevice::isMutingExpectedDevice); + } mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice()); } catch (Exception e) { Log.d(TAG, "Unable to cancel mute await connection"); @@ -711,22 +714,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return false; } - boolean isZeroMode() { - synchronized (mMediaDevicesLock) { - if (mMediaDevices.size() == 1) { - final MediaDevice device = mMediaDevices.iterator().next(); - // Add "pair new" only when local output device exists - final int type = device.getDeviceType(); - if (type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE - || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE - || type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE) { - return true; - } - } - return false; - } - } - void launchBluetoothPairing(View view) { ActivityLaunchAnimator.Controller controller = mDialogLaunchAnimator.createActivityLaunchController(view); @@ -736,7 +723,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } Intent launchIntent = - new Intent(ACTION_BLUETOOTH_PAIRING_SETTINGS) + new Intent(ACTION_BLUETOOTH_SETTINGS) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); final Intent deepLinkIntent = new Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java index 7cf0063481a5..fc4773d3c6dd 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java @@ -134,6 +134,17 @@ public class MediaOutputDialog extends MediaOutputBaseDialog { } } + @Override + public int getBroadcastIconVisibility() { + return (isBroadcastSupported() && mMediaOutputController.isBluetoothLeBroadcastEnabled()) + ? View.VISIBLE : View.GONE; + } + + @Override + public void onBroadcastIconClick() { + startLeBroadcastDialog(); + } + @VisibleForTesting public enum MediaOutputEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "The MediaOutput dialog became visible on the screen.") diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index b01dca1a0365..9e1ba5f723a3 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -72,6 +72,7 @@ import com.android.systemui.navigationbar.buttons.NearestTouchFrame; import com.android.systemui.navigationbar.buttons.RotationContextButton; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.recents.Recents; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shared.rotation.FloatingRotationButton; import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback; import com.android.systemui.shared.rotation.RotationButtonController; @@ -81,7 +82,6 @@ import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.LightBarTransitionsController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.wm.shell.back.BackAnimation; import com.android.wm.shell.pip.Pip; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt index a83367059736..28ab83c83a42 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt @@ -30,6 +30,7 @@ import android.view.Gravity import android.view.MotionEvent import android.view.VelocityTracker import android.view.View +import android.view.ViewConfiguration import android.view.WindowManager import android.view.animation.DecelerateInterpolator import android.view.animation.PathInterpolator @@ -98,6 +99,7 @@ class BackPanelController private constructor( context: Context, private var backAnimation: BackAnimation?, private val windowManager: WindowManager, + private val viewConfiguration: ViewConfiguration, @Main private val mainHandler: Handler, private val vibratorHelper: VibratorHelper, private val configurationController: ConfigurationController, @@ -112,6 +114,7 @@ class BackPanelController private constructor( */ class Factory @Inject constructor( private val windowManager: WindowManager, + private val viewConfiguration: ViewConfiguration, @Main private val mainHandler: Handler, private val vibratorHelper: VibratorHelper, private val configurationController: ConfigurationController, @@ -123,6 +126,7 @@ class BackPanelController private constructor( context, backAnimation, windowManager, + viewConfiguration, mainHandler, vibratorHelper, configurationController, @@ -164,6 +168,10 @@ class BackPanelController private constructor( private var gestureStartTime = 0L + // Whether the current gesture has moved a sufficiently large amount, + // so that we can unambiguously start showing the ENTRY animation + private var hasPassedDragSlop = false + private val failsafeRunnable = Runnable { onFailsafe() } private enum class GestureState { @@ -304,18 +312,17 @@ class BackPanelController private constructor( startX = event.x startY = event.y gestureStartTime = SystemClock.uptimeMillis() - - // Reset the arrow to the side - updateArrowState(GestureState.ENTRY) - - windowManager.updateViewLayout(mView, layoutParams) - mView.startTrackingShowBackArrowLatency() } - MotionEvent.ACTION_MOVE -> handleMoveEvent(event) + MotionEvent.ACTION_MOVE -> { + // only go to the ENTRY state after some minimum motion has occurred + if (dragSlopExceeded(event.x, startX)) { + handleMoveEvent(event) + } + } MotionEvent.ACTION_UP -> { if (currentState == GestureState.ACTIVE) { updateArrowState(if (isFlung()) GestureState.FLUNG else GestureState.COMMITTED) - } else { + } else if (currentState != GestureState.GONE) { // if invisible, skip animation updateArrowState(GestureState.CANCELLED) } velocityTracker = null @@ -330,6 +337,28 @@ class BackPanelController private constructor( } } + /** + * Returns false until the current gesture exceeds the touch slop threshold, + * and returns true thereafter (we reset on the subsequent back gesture). + * The moment it switches from false -> true is important, + * because that's when we switch state, from GONE -> ENTRY. + * @return whether the current gesture has moved past a minimum threshold. + */ + private fun dragSlopExceeded(curX: Float, startX: Float): Boolean { + if (hasPassedDragSlop) return true + + if (abs(curX - startX) > viewConfiguration.scaledTouchSlop) { + // Reset the arrow to the side + updateArrowState(GestureState.ENTRY) + + windowManager.updateViewLayout(mView, layoutParams) + mView.startTrackingShowBackArrowLatency() + + hasPassedDragSlop = true + } + return hasPassedDragSlop + } + private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) { if (!currentState.isInteractive()) return @@ -533,6 +562,7 @@ class BackPanelController private constructor( } private fun resetOnDown() { + hasPassedDragSlop = false hasHapticPlayed = false totalTouchDelta = 0f vibrationTime = 0 diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index bd6a5fc8661b..067f4cbb975e 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -53,7 +53,6 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.ViewConfiguration; import android.view.WindowManager; -import android.view.WindowMetrics; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.policy.GestureNavigationSettingsObserver; @@ -133,7 +132,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker @Override public void onPrioritizedRotation(@Surface.Rotation int rotation) { mStartingQuickstepRotation = rotation; - updateDisabledForQuickstep(mContext.getResources().getConfiguration()); + updateDisabledForQuickstep(mLastReportedConfig); } }; @@ -183,6 +182,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker private final IWindowManager mWindowManagerService; private final Optional<Pip> mPipOptional; private final FalsingManager mFalsingManager; + private final Configuration mLastReportedConfig = new Configuration(); // Activities which should not trigger Back gesture. private final List<ComponentName> mGestureBlockingActivities = new ArrayList<>(); @@ -338,6 +338,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker mLatencyTracker = latencyTracker; mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider; mFeatureFlags = featureFlags; + mLastReportedConfig.setTo(mContext.getResources().getConfiguration()); ComponentName recentsComponentName = ComponentName.unflattenFromString( context.getString(com.android.internal.R.string.config_recentsComponentName)); if (recentsComponentName != null) { @@ -886,12 +887,12 @@ public class EdgeBackGestureHandler extends CurrentUserTracker if (DEBUG_MISSING_GESTURE) { Log.d(DEBUG_MISSING_GESTURE_TAG, "Config changed: config=" + newConfig); } + mLastReportedConfig.updateFrom(newConfig); updateDisplaySize(); } private void updateDisplaySize() { - WindowMetrics metrics = mWindowManager.getMaximumWindowMetrics(); - Rect bounds = metrics.getBounds(); + Rect bounds = mLastReportedConfig.windowConfiguration.getMaxBounds(); mDisplaySize.set(bounds.width(), bounds.height()); if (DEBUG_MISSING_GESTURE) { Log.d(DEBUG_MISSING_GESTURE_TAG, "Update display size: mDisplaySize=" + mDisplaySize); diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java index b55d86e8fb1c..0ba077eb0912 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java @@ -29,7 +29,8 @@ import android.os.UserHandle; import android.util.Log; import android.widget.RemoteViews; -import com.android.systemui.SystemUIAppComponentFactory; +import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback; +import com.android.systemui.SystemUIAppComponentFactoryBase.ContextInitializer; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.shared.system.PeopleProviderUtils; @@ -37,11 +38,11 @@ import javax.inject.Inject; /** API that returns a People Tile preview. */ public class PeopleProvider extends ContentProvider implements - SystemUIAppComponentFactory.ContextInitializer { + ContextInitializer { private static final String TAG = "PeopleProvider"; private static final boolean DEBUG = PeopleSpaceUtils.DEBUG; private static final String EMPTY_STRING = ""; - private SystemUIAppComponentFactory.ContextAvailableCallback mCallback; + private ContextAvailableCallback mCallback; @Inject PeopleSpaceWidgetManager mPeopleSpaceWidgetManager; @@ -144,7 +145,7 @@ public class PeopleProvider extends ContentProvider implements @Override public void setContextAvailableCallback( - SystemUIAppComponentFactory.ContextAvailableCallback callback) { + ContextAvailableCallback callback) { mCallback = callback; } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java index fa2d4447f26d..ee41f1d1077d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java @@ -72,9 +72,9 @@ public class CameraToggleTile extends SensorPrivacyToggleTile { @Override public @DrawableRes int getIconRes(boolean isBlocked) { if (isBlocked) { - return com.android.internal.R.drawable.ic_camera_blocked; + return R.drawable.qs_camera_access_icon_off; } else { - return com.android.internal.R.drawable.ic_camera_allowed; + return R.drawable.qs_camera_access_icon_on; } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 6c58c459c2c2..438236d6a63d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -51,7 +51,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; -import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.Rect; import android.graphics.Region; @@ -97,6 +96,7 @@ import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.settings.CurrentUserTracker; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.recents.model.Task; @@ -105,7 +105,6 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.CentralSurfaces; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; import com.android.systemui.statusbar.policy.CallbackController; import com.android.wm.shell.back.BackAnimation; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java index daaa897374cb..814b8e90e0dd 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java @@ -102,7 +102,7 @@ public class ActionProxyReceiver extends BroadcastReceiver { ? ACTION_TYPE_EDIT : ACTION_TYPE_SHARE; mScreenshotSmartActions.notifyScreenshotAction( - context, intent.getStringExtra(EXTRA_ID), actionType, false, null); + intent.getStringExtra(EXTRA_ID), actionType, false, null); } } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DeleteScreenshotReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/DeleteScreenshotReceiver.java index 8d44205bef30..e0346f2e2a98 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/DeleteScreenshotReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/DeleteScreenshotReceiver.java @@ -62,7 +62,7 @@ public class DeleteScreenshotReceiver extends BroadcastReceiver { }); if (intent.getBooleanExtra(EXTRA_SMART_ACTIONS_ENABLED, false)) { mScreenshotSmartActions.notifyScreenshotAction( - context, intent.getStringExtra(EXTRA_ID), ACTION_TYPE_DELETE, false, null); + intent.getStringExtra(EXTRA_ID), ACTION_TYPE_DELETE, false, null); } } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ReferenceScreenshotModule.java b/packages/SystemUI/src/com/android/systemui/screenshot/ReferenceScreenshotModule.java new file mode 100644 index 000000000000..6224e1bf2414 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ReferenceScreenshotModule.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.screenshot; + +import dagger.Module; +import dagger.Provides; + +/** + * + */ +@Module +public interface ReferenceScreenshotModule { + /** */ + @Provides + static ScreenshotNotificationSmartActionsProvider providesScrnshtNotifSmartActionsProvider() { + return new ScreenshotNotificationSmartActionsProvider(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index 50ee1f7ba97a..f248d6913878 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -38,7 +38,6 @@ import android.graphics.drawable.Icon; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -49,7 +48,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.systemui.R; -import com.android.systemui.SystemUIFactory; import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import com.google.common.util.concurrent.ListenableFuture; @@ -89,7 +87,10 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { SaveImageInBackgroundTask(Context context, ImageExporter exporter, ScreenshotSmartActions screenshotSmartActions, ScreenshotController.SaveImageInBackgroundData data, - Supplier<ActionTransition> sharedElementTransition) { + Supplier<ActionTransition> sharedElementTransition, + ScreenshotNotificationSmartActionsProvider + screenshotNotificationSmartActionsProvider + ) { mContext = context; mScreenshotSmartActions = screenshotSmartActions; mImageData = new ScreenshotController.SavedImageData(); @@ -103,15 +104,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { // Initialize screenshot notification smart actions provider. mSmartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true); - if (mSmartActionsEnabled) { - mSmartActionsProvider = - SystemUIFactory.getInstance() - .createScreenshotNotificationSmartActionsProvider( - context, THREAD_POOL_EXECUTOR, new Handler()); - } else { - // If smart actions is not enabled use empty implementation. - mSmartActionsProvider = new ScreenshotNotificationSmartActionsProvider(); - } + mSmartActionsProvider = screenshotNotificationSmartActionsProvider; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index c213f192291a..89a15f65e98f 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -263,6 +263,8 @@ public class ScreenshotController { private final ScrollCaptureController mScrollCaptureController; private final LongScreenshotData mLongScreenshotHolder; private final boolean mIsLowRamDevice; + private final ScreenshotNotificationSmartActionsProvider + mScreenshotNotificationSmartActionsProvider; private final TimeoutHandler mScreenshotHandler; private ScreenshotView mScreenshotView; @@ -298,7 +300,9 @@ public class ScreenshotController { LongScreenshotData longScreenshotHolder, ActivityManager activityManager, TimeoutHandler timeoutHandler, - BroadcastSender broadcastSender) { + BroadcastSender broadcastSender, + ScreenshotNotificationSmartActionsProvider screenshotNotificationSmartActionsProvider + ) { mScreenshotSmartActions = screenshotSmartActions; mNotificationsController = screenshotNotificationsController; mScrollCaptureClient = scrollCaptureClient; @@ -308,6 +312,7 @@ public class ScreenshotController { mScrollCaptureController = scrollCaptureController; mLongScreenshotHolder = longScreenshotHolder; mIsLowRamDevice = activityManager.isLowRamDevice(); + mScreenshotNotificationSmartActionsProvider = screenshotNotificationSmartActionsProvider; mBgExecutor = Executors.newSingleThreadExecutor(); mBroadcastSender = broadcastSender; @@ -956,7 +961,8 @@ public class ScreenshotController { } mSaveInBgTask = new SaveImageInBackgroundTask(mContext, mImageExporter, - mScreenshotSmartActions, data, getActionTransitionSupplier()); + mScreenshotSmartActions, data, getActionTransitionSupplier(), + mScreenshotNotificationSmartActionsProvider); mSaveInBgTask.execute(); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java index 0527818135dd..68b46d2b7525 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java @@ -16,8 +16,6 @@ package com.android.systemui.screenshot; -import static android.os.AsyncTask.THREAD_POOL_EXECUTOR; - import static com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS; import static com.android.systemui.screenshot.LogConfig.logTag; import static com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType; @@ -25,17 +23,14 @@ import static com.android.systemui.screenshot.ScreenshotNotificationSmartActions import android.app.ActivityManager; import android.app.Notification; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; -import android.os.Handler; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.SystemUIFactory; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -46,6 +41,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.inject.Inject; +import javax.inject.Provider; /** * Collects the static functions for retrieving and acting on smart actions. @@ -53,9 +49,17 @@ import javax.inject.Inject; @SysUISingleton public class ScreenshotSmartActions { private static final String TAG = logTag(ScreenshotSmartActions.class); + private final Provider<ScreenshotNotificationSmartActionsProvider> + mScreenshotNotificationSmartActionsProviderProvider; @Inject - public ScreenshotSmartActions() {} + public ScreenshotSmartActions( + Provider<ScreenshotNotificationSmartActionsProvider> + screenshotNotificationSmartActionsProviderProvider + ) { + mScreenshotNotificationSmartActionsProviderProvider = + screenshotNotificationSmartActionsProviderProvider; + } @VisibleForTesting CompletableFuture<List<Notification.Action>> getSmartActionsFuture( @@ -165,12 +169,11 @@ public class ScreenshotSmartActions { } } - void notifyScreenshotAction(Context context, String screenshotId, String action, + void notifyScreenshotAction(String screenshotId, String action, boolean isSmartAction, Intent intent) { try { ScreenshotNotificationSmartActionsProvider provider = - SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider( - context, THREAD_POOL_EXECUTOR, new Handler()); + mScreenshotNotificationSmartActionsProviderProvider.get(); if (DEBUG_ACTIONS) { Log.d(TAG, String.format("%s notifyAction: %s id=%s, isSmartAction=%b", provider.getClass(), action, screenshotId, isSmartAction)); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java index f703058f4a0f..45af1874e9db 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java @@ -60,7 +60,7 @@ public class SmartActionsReceiver extends BroadcastReceiver { } mScreenshotSmartActions.notifyScreenshotAction( - context, intent.getStringExtra(EXTRA_ID), actionType, true, + intent.getStringExtra(EXTRA_ID), actionType, true, pendingIntent.getIntent()); } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt new file mode 100644 index 000000000000..aa218dbfdd43 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.content.Context +import android.content.SharedPreferences +import java.io.File + +/** + * Interface for retrieving file paths for file storage of system and secondary users. + */ +interface UserFileManager { + /** + * Return the file based on current user. + */ + fun getFile(fileName: String, userId: Int): File + /** + * Get shared preferences from user. + */ + fun getSharedPreferences( + fileName: String, + @Context.PreferencesMode mode: Int, + userId: Int + ): SharedPreferences +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt new file mode 100644 index 000000000000..8c8f54fe9c3d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.SharedPreferences +import android.os.Environment +import android.os.UserHandle +import android.os.UserManager +import android.util.Log +import androidx.annotation.VisibleForTesting +import com.android.systemui.CoreStartable +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.util.concurrency.DelayableExecutor +import java.io.File +import javax.inject.Inject + +/** + * Implementation for retrieving file paths for file storage of system and secondary users. + * Files lie in {File Directory}/UserFileManager/{User Id} for secondary user. + * For system user, we use the conventional {File Directory} + */ +@SysUISingleton +class UserFileManagerImpl @Inject constructor( + // Context of system process and system user. + val context: Context, + val userManager: UserManager, + val broadcastDispatcher: BroadcastDispatcher, + @Background val backgroundExecutor: DelayableExecutor +) : UserFileManager, CoreStartable(context) { + companion object { + private const val FILES = "files" + private const val SHARED_PREFS = "shared_prefs" + internal const val ID = "UserFileManager" + } + + private val broadcastReceiver = object : BroadcastReceiver() { + /** + * Listen to Intent.ACTION_USER_REMOVED to clear user data. + */ + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == Intent.ACTION_USER_REMOVED) { + clearDeletedUserData() + } + } + } + + /** + * Poll for user-specific directories to delete upon start up. + */ + override fun start() { + clearDeletedUserData() + val filter = IntentFilter().apply { + addAction(Intent.ACTION_USER_REMOVED) + } + broadcastDispatcher.registerReceiver(broadcastReceiver, filter, backgroundExecutor) + } + + /** + * Return the file based on current user. + */ + override fun getFile(fileName: String, userId: Int): File { + return if (UserHandle(userId).isSystem) { + Environment.buildPath( + context.filesDir, + fileName + ) + } else { + Environment.buildPath( + context.filesDir, + ID, + userId.toString(), + FILES, + fileName + ) + } + } + + /** + * Get shared preferences from user. + */ + override fun getSharedPreferences( + fileName: String, + @Context.PreferencesMode mode: Int, + userId: Int + ): SharedPreferences { + if (UserHandle(userId).isSystem) { + return context.getSharedPreferences(fileName, mode) + } + val secondaryUserDir = Environment.buildPath( + context.filesDir, + ID, + userId.toString(), + SHARED_PREFS, + fileName + ) + + return context.getSharedPreferences(secondaryUserDir, mode) + } + + /** + * Remove dirs for deleted users. + */ + @VisibleForTesting + internal fun clearDeletedUserData() { + backgroundExecutor.execute { + val file = Environment.buildPath(context.filesDir, ID) + if (!file.exists()) return@execute + val aliveUsers = userManager.aliveUsers.map { it.id.toString() } + val dirsToDelete = file.list().filter { !aliveUsers.contains(it) } + + dirsToDelete.forEach { dir -> + try { + val dirToDelete = Environment.buildPath( + file, + dir, + ) + dirToDelete.deleteRecursively() + } catch (e: Exception) { + Log.e(ID, "Deletion failed.", e) + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java index 7084d3ffc9ff..2f62e44ba4c4 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java +++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java @@ -21,25 +21,28 @@ import android.content.Context; import android.os.Handler; import android.os.UserManager; +import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dump.DumpManager; import com.android.systemui.settings.UserContentResolverProvider; import com.android.systemui.settings.UserContextProvider; +import com.android.systemui.settings.UserFileManager; +import com.android.systemui.settings.UserFileManagerImpl; import com.android.systemui.settings.UserTracker; import com.android.systemui.settings.UserTrackerImpl; import dagger.Binds; import dagger.Module; import dagger.Provides; +import dagger.multibindings.ClassKey; +import dagger.multibindings.IntoMap; /** * Dagger Module for classes found within the com.android.systemui.settings package. */ @Module -public abstract class SettingsModule { - - +public abstract class MultiUserUtilsModule { @Binds @SysUISingleton abstract UserContextProvider bindUserContextProvider(UserTracker tracker); @@ -62,4 +65,12 @@ public abstract class SettingsModule { tracker.initialize(startingUser); return tracker; } + + @Binds + @IntoMap + @ClassKey(UserFileManagerImpl.class) + abstract CoreStartable bindUserFileManagerCoreStartable(UserFileManagerImpl sysui); + + @Binds + abstract UserFileManager bindUserFileManager(UserFileManagerImpl impl); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt b/packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt index d44a56942065..07e8b9fe3123 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt @@ -11,7 +11,7 @@ * KIND, either express or implied. See the License for the specific language governing * permissions and limitations under the License. */ -package com.android.systemui.statusbar.phone +package com.android.systemui.shade import android.view.MotionEvent import com.android.systemui.dump.DumpsysTableLogger diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt index a385e22c1aff..ce9d89f89ae1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEvents.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone +package com.android.systemui.shade /** Provides certain notification panel events. */ interface NotifPanelEvents { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEventsModule.java index 2aaf6a5f4391..67723843086a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotifPanelEventsModule.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotifPanelEventsModule.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import com.android.systemui.dagger.SysUISingleton; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt index ff48755f750a..e0cd482166b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelUnfoldAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone +package com.android.systemui.shade import android.content.Context import android.view.ViewGroup diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java index d9ba494a4d63..e0997ff0f905 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import android.content.Context; import android.graphics.Canvas; @@ -25,6 +25,8 @@ import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.PanelView; +import com.android.systemui.statusbar.phone.TapAgainView; public class NotificationPanelView extends PanelView { @@ -35,8 +37,8 @@ public class NotificationPanelView extends PanelView { */ public static final int FLING_EXPAND = 0; - static final String COUNTER_PANEL_OPEN = "panel_open"; - static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs"; + public static final String COUNTER_PANEL_OPEN = "panel_open"; + public static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs"; private int mCurrentPanelAlpha; private final Paint mAlphaPaint = new Paint(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index b257d14dc4d5..bab92ba492c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; @@ -140,6 +140,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; import com.android.systemui.screenrecord.RecordingController; +import com.android.systemui.shade.transition.ShadeTransitionController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.GestureRecorder; @@ -176,12 +177,35 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; +import com.android.systemui.statusbar.phone.CentralSurfaces; +import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; +import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; +import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; +import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController; +import com.android.systemui.statusbar.phone.KeyguardBouncer; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.KeyguardClockPositionAlgorithm; +import com.android.systemui.statusbar.phone.KeyguardStatusBarView; +import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController; +import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController; +import com.android.systemui.statusbar.phone.LockscreenGestureLogger; import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent; +import com.android.systemui.statusbar.phone.NotificationIconAreaController; +import com.android.systemui.statusbar.phone.PanelView; +import com.android.systemui.statusbar.phone.PanelViewController; +import com.android.systemui.statusbar.phone.PhoneStatusBarView; +import com.android.systemui.statusbar.phone.ScreenOffAnimationController; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.phone.TapAgainViewController; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.phone.panelstate.PanelState; -import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -343,6 +367,8 @@ public final class NotificationPanelViewController extends PanelViewController { private final LockIconViewController mLockIconViewController; private NotificationsQuickSettingsContainer mNotificationContainerParent; private final NotificationsQSContainerController mNotificationsQSContainerController; + private final Provider<KeyguardBottomAreaViewController> + mKeyguardBottomAreaViewControllerProvider; private boolean mAnimateNextPositionUpdate; private float mQuickQsHeaderHeight; private final ScreenOffAnimationController mScreenOffAnimationController; @@ -741,6 +767,7 @@ public final class NotificationPanelViewController extends PanelViewController { InteractionJankMonitor interactionJankMonitor, QsFrameTranslateController qsFrameTranslateController, SysUiState sysUiState, + Provider<KeyguardBottomAreaViewController> keyguardBottomAreaViewControllerProvider, KeyguardUnlockAnimationController keyguardUnlockAnimationController, NotificationListContainer notificationListContainer, PanelEventsEmitter panelEventsEmitter, @@ -782,6 +809,7 @@ public final class NotificationPanelViewController extends PanelViewController { mNotificationsQSContainerController = notificationsQSContainerController; mNotificationListContainer = notificationListContainer; mNotificationStackSizeCalculator = notificationStackSizeCalculator; + mKeyguardBottomAreaViewControllerProvider = keyguardBottomAreaViewControllerProvider; mNotificationsQSContainerController.init(); mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; mNotificationIconAreaController = notificationIconAreaController; @@ -1222,8 +1250,7 @@ public final class NotificationPanelViewController extends PanelViewController { int index = mView.indexOfChild(mKeyguardBottomArea); mView.removeView(mKeyguardBottomArea); KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea; - mKeyguardBottomArea = (KeyguardBottomAreaView) mLayoutInflater.inflate( - R.layout.keyguard_bottom_area, mView, false); + mKeyguardBottomArea = mKeyguardBottomAreaViewControllerProvider.get().getView(); mKeyguardBottomArea.initFrom(oldBottomArea); mView.addView(mKeyguardBottomArea, index); initBottomArea(); @@ -1676,11 +1703,16 @@ public final class NotificationPanelViewController extends PanelViewController { setQsExpansion(mQsMinExpansionHeight); } + @Override + @VisibleForTesting + protected void cancelHeightAnimator() { + super.cancelHeightAnimator(); + } + public void cancelAnimation() { mView.animate().cancel(); } - /** * Animate QS closing by flinging it. * If QS is expanded, it will collapse into QQS and stop. @@ -2974,7 +3006,7 @@ public final class NotificationPanelViewController extends PanelViewController { } @Override - protected int getMaxPanelHeight() { + public int getMaxPanelHeight() { int min = mStatusBarMinHeight; if (!(mBarState == KEYGUARD) && mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) { @@ -3078,7 +3110,7 @@ public final class NotificationPanelViewController extends PanelViewController { } } - boolean isPanelExpanded() { + public boolean isPanelExpanded() { return mPanelExpanded; } @@ -3194,14 +3226,7 @@ public final class NotificationPanelViewController extends PanelViewController { getExpandedFraction()); float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction()); alpha *= mBottomAreaShadeAlpha; - mKeyguardBottomArea.setAffordanceAlpha(alpha); - mKeyguardBottomArea.setImportantForAccessibility( - alpha == 0f ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS - : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); - View ambientIndicationContainer = mCentralSurfaces.getAmbientIndicationContainer(); - if (ambientIndicationContainer != null) { - ambientIndicationContainer.setAlpha(alpha); - } + mKeyguardBottomArea.setComponentAlphas(alpha); mLockIconViewController.setAlpha(alpha); } @@ -3918,7 +3943,6 @@ public final class NotificationPanelViewController extends PanelViewController { * {@link ShadeViewManager}. */ public void updateNotificationViews(String reason) { - mNotificationStackScrollLayoutController.updateSectionBoundaries(reason); mNotificationStackScrollLayoutController.updateFooter(); mNotificationIconAreaController.updateNotificationIcons(createVisibleEntriesList()); @@ -4879,6 +4903,16 @@ public final class NotificationPanelViewController extends PanelViewController { return mStatusBarViewTouchEventHandler; } + @VisibleForTesting + StatusBarStateController getStatusBarStateController() { + return mStatusBarStateController; + } + + @VisibleForTesting + boolean isHintAnimationRunning() { + return mHintAnimationRunning; + } + private void onStatusBarWindowStateChanged(@StatusBarManager.WindowVisibleState int state) { if (state != WINDOW_STATE_SHOWING && mStatusBarStateController.getState() == StatusBarState.SHADE) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java index 1e3a02b0606b..121d69d34678 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import static android.view.WindowInsets.Type.systemBars; @@ -52,6 +52,7 @@ import android.widget.FrameLayout; import com.android.internal.view.FloatingActionMode; import com.android.internal.widget.floatingtoolbar.FloatingToolbar; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.CentralSurfaces; /** * Combined keyguard and notification panel view. Also holding backdrop and scrims. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index be5b33eb0da0..b8546df75f5f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import android.app.StatusBarManager; import android.hardware.display.AmbientDisplayConfiguration; @@ -46,6 +46,9 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.phone.CentralSurfaces; +import com.android.systemui.statusbar.phone.PhoneStatusBarViewController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.window.StatusBarWindowStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt index ebedbf987aa2..13a5615a8b54 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone +package com.android.systemui.shade import android.view.View import android.view.ViewGroup @@ -6,11 +6,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.WindowInsets import androidx.annotation.VisibleForTesting import androidx.constraintlayout.widget.ConstraintSet -import androidx.constraintlayout.widget.ConstraintSet.BOTTOM -import androidx.constraintlayout.widget.ConstraintSet.END -import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID -import androidx.constraintlayout.widget.ConstraintSet.START -import androidx.constraintlayout.widget.ConstraintSet.TOP +import androidx.constraintlayout.widget.ConstraintSet.* import com.android.systemui.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java index 2446cf7ba412..587e0e6dd834 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java @@ -14,7 +14,7 @@ * limitations under the License */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import android.app.Fragment; import android.content.Context; diff --git a/packages/SystemUI/src/com/android/systemui/shade/OWNERS b/packages/SystemUI/src/com/android/systemui/shade/OWNERS new file mode 100644 index 000000000000..133711ee5ab2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/OWNERS @@ -0,0 +1,13 @@ +per-file *Notification* = set noparent +per-file *Notification* = file:../statusbar/notification/OWNERS + +per-file NotificationsQuickSettingsContainer.java = kozynski@google.com, asc@google.com +per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google.com + +per-file NotificationShadeWindowViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com +per-file NotificationShadeWindowView.java = pixel@google.com, cinek@google.com, juliacr@google.com + +per-file NotificationPanelUnfoldAnimationController.kt = alexflo@google.com, jeffdq@google.com, juliacr@google.com + +per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com +per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/NoOpOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/NoOpOverScroller.kt index 2789db874249..f4db3ab9289b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/NoOpOverScroller.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/transition/NoOpOverScroller.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt index 1b8afb9ddc1d..afd57daca10b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import android.content.res.Configuration import android.content.res.Resources diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeOverScroller.kt index f1cedeb21e0a..6c3a028c2380 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeOverScroller.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeOverScroller.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import com.android.systemui.statusbar.phone.panelstate.PanelState diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt index 71c61597ff11..1c4911de1d45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import android.content.Context import android.content.res.Configuration @@ -6,8 +6,8 @@ import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS +import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController -import com.android.systemui.statusbar.phone.NotificationPanelViewController import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager import com.android.systemui.statusbar.phone.panelstate.PanelState diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt index c25aab8eb80f..204dd3c07d8e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import android.animation.Animator import android.animation.ValueAnimator diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 9e029095ea6b..ca147286a301 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -900,16 +900,36 @@ public class KeyguardIndicationController { mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState); } } else { - if (!mAccessibilityManager.isEnabled() - && !mAccessibilityManager.isTouchExplorationEnabled() - && mKeyguardUpdateMonitor.isUdfpsSupported() - && mKeyguardUpdateMonitor.getUserCanSkipBouncer( - KeyguardUpdateMonitor.getCurrentUser())) { - final int stringId = mKeyguardUpdateMonitor.getIsFaceAuthenticated() - ? R.string.keyguard_face_successful_unlock_press - : R.string.keyguard_unlock_press; - showBiometricMessage(mContext.getString(stringId)); + final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer( + KeyguardUpdateMonitor.getCurrentUser()); + if (canSkipBouncer) { + final boolean faceAuthenticated = mKeyguardUpdateMonitor.getIsFaceAuthenticated(); + final boolean udfpsSupported = mKeyguardUpdateMonitor.isUdfpsSupported(); + final boolean a11yEnabled = mAccessibilityManager.isEnabled() + || mAccessibilityManager.isTouchExplorationEnabled(); + if (udfpsSupported && faceAuthenticated) { // co-ex + if (a11yEnabled) { + showBiometricMessage(mContext.getString( + R.string.keyguard_face_successful_unlock_swipe)); + } else { + showBiometricMessage(mContext.getString( + R.string.keyguard_face_successful_unlock_press)); + } + } else if (faceAuthenticated) { // face-only + showBiometricMessage(mContext.getString( + R.string.keyguard_face_successful_unlock_swipe)); + } else if (udfpsSupported) { // udfps-only + if (a11yEnabled) { + showBiometricMessage(mContext.getString(R.string.keyguard_unlock)); + } else { + showBiometricMessage(mContext.getString( + R.string.keyguard_unlock_press)); + } + } else { // no security or unlocked by a trust agent + showBiometricMessage(mContext.getString(R.string.keyguard_unlock)); + } } else { + // suggest swiping up for the primary authentication bouncer showBiometricMessage(mContext.getString(R.string.keyguard_unlock)); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt index 01eb4446ea8e..886ad684649f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt @@ -6,7 +6,7 @@ import android.util.MathUtils import com.android.systemui.R import com.android.systemui.dump.DumpManager import com.android.systemui.media.MediaHierarchyManager -import com.android.systemui.statusbar.phone.NotificationPanelViewController +import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.statusbar.policy.ConfigurationController import dagger.assisted.Assisted import dagger.assisted.AssistedFactory diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index 9d80d5fbc2ca..74d8f1beaec1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -29,6 +29,7 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QS import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView @@ -37,7 +38,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.LSShadeTransitionLogger -import com.android.systemui.statusbar.phone.NotificationPanelViewController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.LargeScreenUtils import java.io.PrintWriter diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt index b764c271de45..31b21c9b5321 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt @@ -4,10 +4,10 @@ import android.view.ViewGroup import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.LaunchAnimator +import com.android.systemui.shade.NotificationShadeWindowViewController import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.phone.HeadsUpManagerPhone -import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent import com.android.systemui.statusbar.policy.HeadsUpUtil import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt index a57440c95271..f662a040fae6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.notification.collection import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.notification.NotifPipelineFlags import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener @@ -250,4 +249,4 @@ class NotifPipeline @Inject constructor( fun getInternalNotifUpdater(name: String?): InternalNotifUpdater { return mNotifCollection.getInternalNotifUpdater(name) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt index 5a281b130347..657c394d4e30 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt @@ -145,4 +145,4 @@ class ViewConfigCoordinator @Inject internal constructor( private const val TAG = "ViewConfigCoordinator" private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java index 0833df505bf3..d3bc257d8a54 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java @@ -28,13 +28,13 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotifPanelEvents; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager; import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; -import com.android.systemui.statusbar.phone.NotifPanelEvents; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.Compile; import com.android.systemui.util.concurrency.DelayableExecutor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java index 7dd3672a6e30..a7719d3d82a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java @@ -23,6 +23,7 @@ import android.service.notification.NotificationStats; import androidx.annotation.NonNull; +import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason; @@ -33,10 +34,13 @@ import com.android.systemui.statusbar.notification.collection.render.Notificatio import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; import com.android.systemui.statusbar.policy.HeadsUpManager; +import javax.inject.Inject; + /** * Callback for when a user interacts with a {@see ExpandableNotificationRow}. Sends relevant * information about the interaction to the notification pipeline. */ +@SysUISingleton public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback { private final NotificationVisibilityProvider mVisibilityProvider; private final NotifCollection mNotifCollection; @@ -44,6 +48,7 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback private final StatusBarStateController mStatusBarStateController; private final VisualStabilityCoordinator mVisualStabilityCoordinator; + @Inject public OnUserInteractionCallbackImpl( NotificationVisibilityProvider visibilityProvider, NotifCollection notifCollection, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java deleted file mode 100644 index bdbb0eb48e8a..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification.collection.legacy; - -import static com.android.systemui.statusbar.phone.CentralSurfaces.SPEW; - -import android.service.notification.StatusBarNotification; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; - -import org.jetbrains.annotations.NotNull; - -import javax.inject.Inject; - -/** - * This is some logic extracted from the - * {@link com.android.systemui.statusbar.phone.StatusBarNotificationPresenter} - * into a class that implements a new-pipeline interface so that the new pipeline can implement it - * correctly. - * - * Specifically, this is the logic which updates notifications when uiMode and screen properties - * change, and which closes the shade when the last notification disappears. - */ -public class LegacyNotificationPresenterExtensions implements NotifShadeEventSource { - private static final String TAG = "LegacyNotifPresenter"; - private final NotificationEntryManager mEntryManager; - private boolean mEntryListenerAdded; - private Runnable mShadeEmptiedCallback; - private Runnable mNotifRemovedByUserCallback; - - @Inject - public LegacyNotificationPresenterExtensions(NotificationEntryManager entryManager) { - mEntryManager = entryManager; - } - - private void ensureEntryListenerAdded() { - if (mEntryListenerAdded) return; - mEntryListenerAdded = true; - mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { - @Override - public void onEntryRemoved( - @NotNull NotificationEntry entry, - NotificationVisibility visibility, - boolean removedByUser, - int reason) { - StatusBarNotification old = entry.getSbn(); - if (SPEW) { - Log.d(TAG, "removeNotification key=" + entry.getKey() - + " old=" + old + " reason=" + reason); - } - - if (old != null && !mEntryManager.hasActiveNotifications()) { - if (mShadeEmptiedCallback != null) mShadeEmptiedCallback.run(); - } - if (removedByUser) { - if (mNotifRemovedByUserCallback != null) mNotifRemovedByUserCallback.run(); - } - } - }); - } - - @Override - public void setNotifRemovedByUserCallback(@NonNull Runnable callback) { - if (mNotifRemovedByUserCallback != null) { - throw new IllegalStateException("mNotifRemovedByUserCallback already set"); - } - mNotifRemovedByUserCallback = callback; - ensureEntryListenerAdded(); - } - - @Override - public void setShadeEmptiedCallback(@NonNull Runnable callback) { - if (mShadeEmptiedCallback != null) { - throw new IllegalStateException("mShadeEmptiedCallback already set"); - } - mShadeEmptiedCallback = callback; - ensureEntryListenerAdded(); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java deleted file mode 100644 index 103b14b09e9c..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification.collection.legacy; - -import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; - -import android.service.notification.NotificationListenerService; -import android.service.notification.NotificationStats; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; -import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; -import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; -import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; -import com.android.systemui.statusbar.policy.HeadsUpManager; - -/** - * Callback for when a user interacts with a {@see ExpandableNotificationRow}. - */ -public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCallback { - private final NotificationEntryManager mNotificationEntryManager; - private final NotificationVisibilityProvider mVisibilityProvider; - private final HeadsUpManager mHeadsUpManager; - private final StatusBarStateController mStatusBarStateController; - private final VisualStabilityManager mVisualStabilityManager; - private final GroupMembershipManager mGroupMembershipManager; - - public OnUserInteractionCallbackImplLegacy( - NotificationEntryManager notificationEntryManager, - NotificationVisibilityProvider visibilityProvider, - HeadsUpManager headsUpManager, - StatusBarStateController statusBarStateController, - VisualStabilityManager visualStabilityManager, - GroupMembershipManager groupMembershipManager - ) { - mNotificationEntryManager = notificationEntryManager; - mVisibilityProvider = visibilityProvider; - mHeadsUpManager = headsUpManager; - mStatusBarStateController = statusBarStateController; - mVisualStabilityManager = visualStabilityManager; - mGroupMembershipManager = groupMembershipManager; - } - - /** - * Callback triggered when a user: - * 1. Manually dismisses a notification {@see ExpandableNotificationRow}. - * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}. - * {@see StatusBarNotificationActivityStarter} - * - * @param groupSummaryToDismiss the group summary that should be dismissed - * along with this dismissal. If null, does not additionally - * dismiss any notifications. - */ - private void onDismiss( - NotificationEntry entry, - @NotificationListenerService.NotificationCancelReason int cancellationReason, - @Nullable NotificationEntry groupSummaryToDismiss - ) { - int dismissalSurface = NotificationStats.DISMISSAL_SHADE; - if (mHeadsUpManager.isAlerting(entry.getKey())) { - dismissalSurface = NotificationStats.DISMISSAL_PEEK; - } else if (mStatusBarStateController.isDozing()) { - dismissalSurface = NotificationStats.DISMISSAL_AOD; - } - - if (groupSummaryToDismiss != null) { - onDismiss(groupSummaryToDismiss, cancellationReason, null); - } - - mNotificationEntryManager.performRemoveNotification( - entry.getSbn(), - new DismissedByUserStats( - dismissalSurface, - DISMISS_SENTIMENT_NEUTRAL, - mVisibilityProvider.obtain(entry, true)), - cancellationReason - ); - - } - - @Override - public void onImportanceChanged(NotificationEntry entry) { - mVisualStabilityManager.temporarilyAllowReordering(); - } - - /** - * @param entry that is being dismissed - * @return the group summary to dismiss along with this entry if this is the last entry in - * the group. Else, returns null. - */ - @Nullable - private NotificationEntry getGroupSummaryToDismiss(NotificationEntry entry) { - if (mGroupMembershipManager.isOnlyChildInGroup(entry)) { - NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry); - return groupSummary.isDismissable() ? groupSummary : null; - } - return null; - } - - @Override - @NonNull - public Runnable registerFutureDismissal(@NonNull NotificationEntry entry, - @CancellationReason int cancellationReason) { - NotificationEntry groupSummaryToDismiss = getGroupSummaryToDismiss(entry); - return () -> onDismiss(entry, cancellationReason, groupSummaryToDismiss); - } -} - diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt index 6a1e36f4f469..ec10aaf3cfe3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.collection.provider import com.android.internal.statusbar.NotificationVisibility +import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection @@ -25,6 +26,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationLogger import javax.inject.Inject /** pipeline-agnostic implementation for getting [NotificationVisibility]. */ +@SysUISingleton class NotificationVisibilityProviderImpl @Inject constructor( private val notifDataStore: NotifLiveDataStore, private val notifCollection: CommonNotifCollection @@ -46,4 +48,4 @@ class NotificationVisibilityProviderImpl @Inject constructor( NotificationLogger.getNotificationLocation(notifCollection.getEntry(key)) private fun getCount() = notifDataStore.activeNotifCount.value -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java index a2cb9509a621..1b3f83d1892f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.collection.render; +import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -28,10 +29,13 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Set; +import javax.inject.Inject; + /** * Provides grouping information for notification entries including information about a group's * expanded state. */ +@SysUISingleton public class GroupExpansionManagerImpl implements GroupExpansionManager, Coordinator { private final GroupMembershipManager mGroupMembershipManager; private final Set<OnGroupExpansionChangeListener> mOnGroupChangeListeners = new HashSet<>(); @@ -39,6 +43,7 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Coordin // Set of summary keys whose groups are expanded private final Set<NotificationEntry> mExpandedGroups = new HashSet<>(); + @Inject public GroupExpansionManagerImpl(GroupMembershipManager groupMembershipManager) { mGroupMembershipManager = groupMembershipManager; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 27a7cd779405..4956a27698bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -35,29 +35,26 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.settings.UserContextProvider; +import com.android.systemui.shade.NotifPanelEventsModule; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.notification.AssistantFeedbackController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger; -import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotifPipelineChoreographerModule; import com.android.systemui.statusbar.notification.collection.coordinator.ShadeEventCoordinator; -import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator; import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorsModule; import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager; import com.android.systemui.statusbar.notification.collection.inflation.BindEventManagerImpl; import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder; import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl; -import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationPresenterExtensions; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; -import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; @@ -88,9 +85,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationSectionsMan import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.NotifPanelEventsModule; import com.android.systemui.statusbar.phone.ShadeController; -import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.wmshell.BubblesManager; @@ -116,12 +111,10 @@ import dagger.Provides; }) public interface NotificationsModule { @Binds - StackScrollAlgorithm.SectionProvider bindSectionProvider( - NotificationSectionsManager impl); + StackScrollAlgorithm.SectionProvider bindSectionProvider(NotificationSectionsManager impl); @Binds - StackScrollAlgorithm.BypassController bindBypassController( - KeyguardBypassController impl); + StackScrollAlgorithm.BypassController bindBypassController(KeyguardBypassController impl); /** Provides an instance of {@link NotificationEntryManager} */ @SysUISingleton @@ -194,12 +187,8 @@ public interface NotificationsModule { } /** Provides an instance of {@link NotifGutsViewManager} */ - @SysUISingleton - @Provides - static NotifGutsViewManager provideNotifGutsViewManager( - NotificationGutsManager notificationGutsManager) { - return notificationGutsManager; - } + @Binds + NotifGutsViewManager bindNotifGutsViewManager(NotificationGutsManager notificationGutsManager); /** Provides an instance of {@link VisualStabilityManager} */ @SysUISingleton @@ -253,25 +242,13 @@ public interface NotificationsModule { /** Provides an instance of {@link GroupMembershipManager} */ @SysUISingleton @Provides - static GroupMembershipManager provideGroupMembershipManager( - NotifPipelineFlags notifPipelineFlags, - Lazy<NotificationGroupManagerLegacy> groupManagerLegacy) { - return notifPipelineFlags.isNewPipelineEnabled() - ? new GroupMembershipManagerImpl() - : groupManagerLegacy.get(); + static GroupMembershipManager provideGroupMembershipManager() { + return new GroupMembershipManagerImpl(); } /** Provides an instance of {@link GroupExpansionManager} */ - @SysUISingleton - @Provides - static GroupExpansionManager provideGroupExpansionManager( - NotifPipelineFlags notifPipelineFlags, - Lazy<GroupMembershipManager> groupMembershipManager, - Lazy<NotificationGroupManagerLegacy> groupManagerLegacy) { - return notifPipelineFlags.isNewPipelineEnabled() - ? new GroupExpansionManagerImpl(groupMembershipManager.get()) - : groupManagerLegacy.get(); - } + @Binds + GroupExpansionManager provideGroupExpansionManager(GroupExpansionManagerImpl impl); /** Initializes the notification data pipeline (can be disabled via config). */ @SysUISingleton @@ -290,69 +267,28 @@ public interface NotificationsModule { /** * Provide the active notification collection managing the notifications to render. */ - @Provides - @SysUISingleton - static CommonNotifCollection provideCommonNotifCollection( - NotifPipelineFlags notifPipelineFlags, - Lazy<NotifPipeline> pipeline, - NotificationEntryManager entryManager) { - return notifPipelineFlags.isNewPipelineEnabled() - ? pipeline.get() : entryManager; - } + @Binds + CommonNotifCollection provideCommonNotifCollection(NotifPipeline pipeline); /** * Provide the object which can be used to obtain NotificationVisibility objects. */ @Binds - @SysUISingleton NotificationVisibilityProvider provideNotificationVisibilityProvider( - NotificationVisibilityProviderImpl newProvider); + NotificationVisibilityProviderImpl impl); /** * Provide the active implementation for presenting notifications. */ - @Provides - @SysUISingleton - static NotifShadeEventSource provideNotifShadeEventSource( - NotifPipelineFlags notifPipelineFlags, - Lazy<ShadeEventCoordinator> shadeEventCoordinatorLazy, - Lazy<LegacyNotificationPresenterExtensions> legacyNotificationPresenterExtensionsLazy) { - return notifPipelineFlags.isNewPipelineEnabled() - ? shadeEventCoordinatorLazy.get() - : legacyNotificationPresenterExtensionsLazy.get(); - } + @Binds + NotifShadeEventSource provideNotifShadeEventSource(ShadeEventCoordinator shadeEventCoordinator); /** * Provide a dismissal callback that's triggered when a user manually dismissed a notification * from the notification shade or it gets auto-cancelled by click. */ - @Provides - @SysUISingleton - static OnUserInteractionCallback provideOnUserInteractionCallback( - NotifPipelineFlags notifPipelineFlags, - HeadsUpManager headsUpManager, - StatusBarStateController statusBarStateController, - Lazy<NotifCollection> notifCollection, - Lazy<NotificationVisibilityProvider> visibilityProvider, - Lazy<VisualStabilityCoordinator> visualStabilityCoordinator, - NotificationEntryManager entryManager, - VisualStabilityManager visualStabilityManager, - Lazy<GroupMembershipManager> groupMembershipManagerLazy) { - return notifPipelineFlags.isNewPipelineEnabled() - ? new OnUserInteractionCallbackImpl( - visibilityProvider.get(), - notifCollection.get(), - headsUpManager, - statusBarStateController, - visualStabilityCoordinator.get()) - : new OnUserInteractionCallbackImplLegacy( - entryManager, - visibilityProvider.get(), - headsUpManager, - statusBarStateController, - visualStabilityManager, - groupMembershipManagerLazy.get()); - } + @Binds + OnUserInteractionCallback provideOnUserInteractionCallback(OnUserInteractionCallbackImpl impl); /** */ @Binds diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 2fd02d9f1cd9..defae5b6941f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.stack; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL; import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT; import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE; import static com.android.systemui.util.DumpUtilsKt.println; @@ -5246,6 +5247,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable setClearAllInProgress(true); mShadeNeedsToClose = closeShade; + InteractionJankMonitor.getInstance().begin(this, CUJ_SHADE_CLEAR_ALL); // Decrease the delay for every row we animate to give the sense of // accelerating the swipes final int rowDelayDecrement = 5; @@ -6158,6 +6160,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private void onClearAllAnimationsEnd( List<ExpandableNotificationRow> viewsToRemove, @SelectedRows int selectedRows) { + InteractionJankMonitor.getInstance().end(CUJ_SHADE_CLEAR_ALL); if (mClearAllAnimationListener != null) { mClearAllAnimationListener.onAnimationEnd(viewsToRemove, selectedRows); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index a0d940e835ff..596b767bb434 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -28,7 +28,6 @@ import static com.android.systemui.statusbar.notification.stack.NotificationStac import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows; -import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.canChildBeCleared; import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY; import android.content.res.Configuration; @@ -38,12 +37,10 @@ import android.graphics.PointF; import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; -import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; import android.util.Pair; import android.view.Display; -import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -53,20 +50,17 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; import com.android.systemui.SwipeHelper; import com.android.systemui.classifier.Classifier; import com.android.systemui.classifier.FalsingCollector; -import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.media.KeyguardMediaController; @@ -75,6 +69,7 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener; @@ -85,9 +80,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.LaunchAnimationParameters; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.NotificationActivityStarter; -import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -118,7 +111,6 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; -import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -163,13 +155,10 @@ public class NotificationStackScrollLayoutController { private final Resources mResources; private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder; private final ScrimController mScrimController; - private final NotifPipelineFlags mNotifPipelineFlags; private final NotifPipeline mNotifPipeline; private final NotifCollection mNotifCollection; private final NotificationEntryManager mNotificationEntryManager; - private final IStatusBarService mIStatusBarService; private final UiEventLogger mUiEventLogger; - private final LayoutInflater mLayoutInflater; private final NotificationRemoteInputManager mRemoteInputManager; private final VisualStabilityManager mVisualStabilityManager; private final ShadeController mShadeController; @@ -206,8 +195,6 @@ public class NotificationStackScrollLayoutController { @Nullable private NotificationActivityStarter mNotificationActivityStarter; - private ColorExtractor.OnColorsChangedListener mOnColorsChangedListener; - @VisibleForTesting final View.OnAttachStateChangeListener mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() { @@ -256,10 +243,7 @@ public class NotificationStackScrollLayoutController { mView.setAnimateBottomOnLayout(true); } // Let's update the footer once the notifications have been updated (in the next frame) - mView.post(() -> { - updateFooter(); - updateSectionBoundaries("dynamic privacy changed"); - }); + mView.post(this::updateFooter); }; @VisibleForTesting @@ -634,7 +618,6 @@ public class NotificationStackScrollLayoutController { KeyguardMediaController keyguardMediaController, KeyguardBypassController keyguardBypassController, ZenModeController zenModeController, - SysuiColorExtractor colorExtractor, NotificationLockscreenUserManager lockscreenUserManager, MetricsLogger metricsLogger, DumpManager dumpManager, @@ -647,15 +630,12 @@ public class NotificationStackScrollLayoutController { NotificationGroupManagerLegacy legacyGroupManager, GroupExpansionManager groupManager, @SilentHeader SectionHeaderController silentHeaderController, - NotifPipelineFlags notifPipelineFlags, NotifPipeline notifPipeline, NotifCollection notifCollection, NotificationEntryManager notificationEntryManager, LockscreenShadeTransitionController lockscreenShadeTransitionController, ShadeTransitionController shadeTransitionController, - IStatusBarService iStatusBarService, UiEventLogger uiEventLogger, - LayoutInflater layoutInflater, NotificationRemoteInputManager remoteInputManager, VisualStabilityManager visualStabilityManager, ShadeController shadeController, @@ -698,14 +678,11 @@ public class NotificationStackScrollLayoutController { mCentralSurfaces.requestNotificationUpdate("onGroupsChanged"); } }); - mNotifPipelineFlags = notifPipelineFlags; mSilentHeaderController = silentHeaderController; mNotifPipeline = notifPipeline; mNotifCollection = notifCollection; mNotificationEntryManager = notificationEntryManager; - mIStatusBarService = iStatusBarService; mUiEventLogger = uiEventLogger; - mLayoutInflater = layoutInflater; mRemoteInputManager = remoteInputManager; mVisualStabilityManager = visualStabilityManager; mShadeController = shadeController; @@ -745,21 +722,12 @@ public class NotificationStackScrollLayoutController { .setOnMenuEventListener(mMenuEventListener) .build(); - if (mNotifPipelineFlags.isNewPipelineEnabled()) { - mNotifPipeline.addCollectionListener(new NotifCollectionListener() { - @Override - public void onEntryUpdated(NotificationEntry entry) { - mView.onEntryUpdated(entry); - } - }); - } else { - mNotificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { - @Override - public void onPreEntryUpdated(NotificationEntry entry) { - mView.onEntryUpdated(entry); - } - }); - } + mNotifPipeline.addCollectionListener(new NotifCollectionListener() { + @Override + public void onEntryUpdated(NotificationEntry entry) { + mView.onEntryUpdated(entry); + } + }); mView.initView(mView.getContext(), mSwipeHelper, mNotificationStackSizeCalculator); mView.setKeyguardBypassEnabled(mKeyguardBypassController.getBypassEnabled()); @@ -1231,10 +1199,6 @@ public class NotificationStackScrollLayoutController { Trace.endSection(); } - public boolean areNotificationsHiddenInShade() { - return mZenModeController.areNotificationsHiddenInShade(); - } - public boolean isShowingEmptyShadeView() { return mShowEmptyShadeView; } @@ -1339,15 +1303,6 @@ public class NotificationStackScrollLayoutController { }; } - public void updateSectionBoundaries(String reason) { - if (mNotifPipelineFlags.isNewPipelineEnabled()) { - return; - } - Trace.beginSection("NSSLC.updateSectionBoundaries"); - mView.updateSectionBoundaries(reason); - Trace.endSection(); - } - public void updateFooter() { Trace.beginSection("NSSLC.updateFooter"); mView.updateFooter(); @@ -1463,39 +1418,18 @@ public class NotificationStackScrollLayoutController { private void onAnimationEnd(List<ExpandableNotificationRow> viewsToRemove, @SelectedRows int selectedRows) { - if (mNotifPipelineFlags.isNewPipelineEnabled()) { - if (selectedRows == ROWS_ALL) { - mNotifCollection.dismissAllNotifications( - mLockscreenUserManager.getCurrentUserId()); - } else { - final List<Pair<NotificationEntry, DismissedByUserStats>> - entriesWithRowsDismissedFromShade = new ArrayList<>(); - for (ExpandableNotificationRow row : viewsToRemove) { - final NotificationEntry entry = row.getEntry(); - entriesWithRowsDismissedFromShade.add( - new Pair<>(entry, getDismissedByUserStats(entry))); - } - mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade); - } + if (selectedRows == ROWS_ALL) { + mNotifCollection.dismissAllNotifications( + mLockscreenUserManager.getCurrentUserId()); } else { - for (ExpandableNotificationRow rowToRemove : viewsToRemove) { - if (canChildBeCleared(rowToRemove)) { - mNotificationEntryManager.performRemoveNotification( - rowToRemove.getEntry().getSbn(), - getDismissedByUserStats(rowToRemove.getEntry()), - NotificationListenerService.REASON_CANCEL_ALL); - } else { - rowToRemove.resetTranslation(); - } - } - if (selectedRows == ROWS_ALL) { - try { - // TODO(b/169585328): Do not clear media player notifications - mIStatusBarService.onClearAllNotifications( - mLockscreenUserManager.getCurrentUserId()); - } catch (Exception ignored) { - } + final List<Pair<NotificationEntry, DismissedByUserStats>> + entriesWithRowsDismissedFromShade = new ArrayList<>(); + for (ExpandableNotificationRow row : viewsToRemove) { + final NotificationEntry entry = row.getEntry(); + entriesWithRowsDismissedFromShade.add( + new Pair<>(entry, getDismissedByUserStats(entry))); } + mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index dc228bba0de1..5a8050814c8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -47,6 +47,9 @@ import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.qs.QSPanelController; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.statusbar.GestureRecorder; import com.android.systemui.statusbar.LightRevealScrim; import com.android.systemui.statusbar.NotificationPresenter; @@ -265,9 +268,6 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn boolean isPulsing(); - @Nullable - View getAmbientIndicationContainer(); - boolean isOccluded(); //TODO: These can / should probably be moved to NotificationPresenter or ShadeController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index cb9afe887ab7..53b5b0caf257 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -55,6 +55,9 @@ import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.qs.QSPanelController; +import com.android.systemui.shade.NotificationPanelView; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; import com.android.systemui.statusbar.SysuiStatusBarStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 9f65350ec0fd..fff7b6a9e4f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -174,6 +174,9 @@ import com.android.systemui.qs.QSPanelController; import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.scrim.ScrimView; import com.android.systemui.settings.brightness.BrightnessSliderController; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.AutoHideUiElement; import com.android.systemui.statusbar.BackDropView; @@ -1167,9 +1170,6 @@ public class CentralSurfacesImpl extends CoreStartable implements mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView); mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener()); - if (!mNotifPipelineFlags.isNewPipelineEnabled()) { - mHeadsUpManager.addListener(mVisualStabilityManager); - } mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager); createNavigationBar(result); @@ -1861,12 +1861,6 @@ public class CentralSurfacesImpl extends CoreStartable implements return mDozeServiceHost.isPulsing(); } - @androidx.annotation.Nullable - @Override - public View getAmbientIndicationContainer() { - return mAmbientIndicationContainer; - } - /** * When the keyguard is showing and covered by a "showWhenLocked" activity it * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager} @@ -4336,9 +4330,6 @@ public class CentralSurfacesImpl extends CoreStartable implements Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration()); } - if (!mNotifPipelineFlags.isNewPipelineEnabled()) { - mViewHierarchyManager.updateRowStates(); - } mScreenPinningRequest.onConfigurationChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index 55b310ff986d..80c3e6ce989d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -40,6 +40,8 @@ import com.android.systemui.doze.DozeLog; import com.android.systemui.doze.DozeReceiver; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 9863a0ed1ce0..484441a1e76b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -26,6 +26,7 @@ import com.android.internal.widget.ViewClippingUtil; import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.HeadsUpStatusBarView; @@ -40,8 +41,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.ViewController; -import java.util.Optional; import java.util.ArrayList; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 415bd90ed23a..80432dbd277c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -217,8 +217,9 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, * Notify that the status bar panel gets expanded or collapsed. * * @param isExpanded True to notify expanded, false to notify collapsed. + * TODO(b/237811427) replace with a listener */ - void setIsPanelExpanded(boolean isExpanded) { + public void setIsPanelExpanded(boolean isExpanded) { if (isExpanded != mIsExpanded) { mIsExpanded = isExpanded; if (isExpanded) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java index 42f301d2f222..6bfb0dad28f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java @@ -21,6 +21,7 @@ import android.view.MotionEvent; import android.view.ViewConfiguration; import com.android.systemui.Gefingerpoken; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; 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 a6fcde3be2a8..43a5451f4bb6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -39,6 +39,7 @@ import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.view.WindowInsets; import android.widget.FrameLayout; import android.widget.ImageView; @@ -62,6 +63,9 @@ import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.wallet.controller.QuickAccessWalletController; +import java.util.ArrayList; +import java.util.List; + /** * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status * text. @@ -347,8 +351,17 @@ public class KeyguardBottomAreaView extends FrameLayout { dozeTimeTick(); } - public View getIndicationArea() { - return mIndicationArea; + /** + * Returns a list of animators to use to animate the indication areas. + */ + public List<ViewPropertyAnimator> getIndicationAreaAnimators() { + List<ViewPropertyAnimator> animators = + new ArrayList<>(mAmbientIndicationArea != null ? 2 : 1); + animators.add(mIndicationArea.animate()); + if (mAmbientIndicationArea != null) { + animators.add(mAmbientIndicationArea.animate()); + } + return animators; } @Override @@ -418,9 +431,17 @@ public class KeyguardBottomAreaView extends FrameLayout { } /** - * Sets the alpha of the indication areas and affordances, excluding the lock icon. + * Sets the alpha of various sub-components, for example the indication areas and bottom quick + * action buttons. Does not set the alpha of the lock icon. */ - public void setAffordanceAlpha(float alpha) { + public void setComponentAlphas(float alpha) { + setImportantForAccessibility( + alpha == 0f + ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); + if (mAmbientIndicationArea != null) { + mAmbientIndicationArea.setAlpha(alpha); + } mIndicationArea.setAlpha(alpha); mWalletButton.setAlpha(alpha); mQRCodeScannerButton.setAlpha(alpha); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt new file mode 100644 index 000000000000..3942dae7e0c3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone + +import com.android.systemui.util.ViewController +import javax.inject.Inject + +class KeyguardBottomAreaViewController @Inject constructor(view: KeyguardBottomAreaView) : + ViewController<KeyguardBottomAreaView> (view) { + override fun onViewAttached() { + } + + override fun onViewDetached() { + } + + fun getView(): KeyguardBottomAreaView { + // TODO: remove this method. + return mView + } +} 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 ed3d4ad8ad5d..0001cd0a2798 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -266,6 +266,9 @@ public class KeyguardBouncer { private void setVisibility(@View.Visibility int visibility) { mContainer.setVisibility(visibility); + if (mKeyguardViewController != null) { + mKeyguardViewController.onBouncerVisibilityChanged(visibility); + } dispatchVisibilityChanged(); } @@ -397,10 +400,6 @@ public class KeyguardBouncer { return mShowingSoon || mExpansion != EXPANSION_HIDDEN && mExpansion != EXPANSION_VISIBLE; } - public boolean getShowingSoon() { - return mShowingSoon; - } - /** * @return {@code true} when bouncer's pre-hide animation already started but isn't completely * hidden yet, {@code false} otherwise. @@ -645,7 +644,7 @@ public class KeyguardBouncer { /** * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}. * This is NOT called each time the bouncer is shown, but rather only when the fully - * shown amount has changed based on the panel expansion. The bouncer is visibility + * shown amount has changed based on the panel expansion. The bouncer's visibility * can still change when the expansion amount hasn't changed. * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index dde6b168b350..01af48616b65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -27,6 +27,7 @@ import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java index def574c1890f..f06b346780da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java @@ -42,6 +42,7 @@ import com.android.systemui.animation.Interpolators; import com.android.systemui.battery.BatteryMeterViewController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; 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 a8da554d7e1f..905a5f943f0d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java @@ -44,6 +44,8 @@ import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManagerGlobal; +import androidx.lifecycle.ViewTreeLifecycleOwner; + import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; import com.android.systemui.R; @@ -52,6 +54,7 @@ import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.lifecycle.WindowAddedViewLifecycleOwner; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.NotificationShadeWindowController; @@ -241,6 +244,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; mWindowManager.addView(mNotificationShadeView, mLp); + + // Set up and "inject" a LifecycleOwner bound to the Window-View relationship such that all + // views in the sub-tree rooted under this view can access the LifecycleOwner using + // ViewTreeLifecycleOwner.get(...). + if (ViewTreeLifecycleOwner.get(mNotificationShadeView) == null) { + ViewTreeLifecycleOwner.set( + mNotificationShadeView, + new WindowAddedViewLifecycleOwner(mNotificationShadeView)); + } + mLpChanged.copyFrom(mLp); onThemeChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS index f5828f914eab..4657e9b84550 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS @@ -3,14 +3,4 @@ per-file *Notification* = file:../notification/OWNERS per-file NotificationIcon* = ccassidy@google.com, evanlaird@google.com, pixel@google.com -per-file NotificationsQuickSettingsContainer.java = kozynski@google.com, asc@google.com -per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google.com - per-file NotificationShadeWindowControllerImpl.java = dupin@google.com, cinek@google.com, beverlyt@google.com, pixel@google.com, juliacr@google.com -per-file NotificationShadeWindowViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com -per-file NotificationShadeWindowView.java = pixel@google.com, cinek@google.com, juliacr@google.com - -per-file NotificationPanelUnfoldAnimationController.kt = alexflo@google.com, jeffdq@google.com, juliacr@google.com - -per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com -per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index d2fc1af010b9..3a85a3ea6391 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -41,6 +41,7 @@ import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.view.ViewTreeObserver; import android.view.animation.Interpolator; @@ -66,6 +67,7 @@ import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.animation.FlingAnimationUtils; import java.io.PrintWriter; +import java.util.List; public abstract class PanelViewController { public static final boolean DEBUG = PanelView.DEBUG; @@ -599,9 +601,7 @@ public abstract class PanelViewController { float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) { if (target == mExpandedHeight && mOverExpansion == 0.0f) { // We're at the target and didn't fling and there's no overshoot - endJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE); - mKeyguardStateController.notifyPanelFlingEnd(); - notifyExpandingFinished(); + onFlingEnd(false /* cancelled */); return; } mIsFlinging = true; @@ -717,7 +717,7 @@ public abstract class PanelViewController { animator.start(); } - void onFlingEnd(boolean cancelled) { + protected void onFlingEnd(boolean cancelled) { mIsFlinging = false; // No overshoot when the animation ends setOverExpansionInternal(0, false /* isFromGesture */); @@ -1034,16 +1034,19 @@ public abstract class PanelViewController { animator.start(); setAnimator(animator); - View[] viewsToAnimate = { - mKeyguardBottomArea.getIndicationArea(), - mCentralSurfaces.getAmbientIndicationContainer()}; - for (View v : viewsToAnimate) { - if (v == null) { - continue; - } - v.animate().translationY(-mHintDistance).setDuration(250).setInterpolator( - Interpolators.FAST_OUT_SLOW_IN).withEndAction(() -> v.animate().translationY( - 0).setDuration(450).setInterpolator(mBounceInterpolator).start()).start(); + final List<ViewPropertyAnimator> indicationAnimators = + mKeyguardBottomArea.getIndicationAreaAnimators(); + for (final ViewPropertyAnimator indicationAreaAnimator : indicationAnimators) { + indicationAreaAnimator + .translationY(-mHintDistance) + .setDuration(250) + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + .withEndAction(() -> indicationAreaAnimator + .translationY(0) + .setDuration(450) + .setInterpolator(mBounceInterpolator) + .start()) + .start(); } } @@ -1110,7 +1113,7 @@ public abstract class PanelViewController { } /** Returns true if {@link PanelView} should be visible. */ - abstract boolean shouldPanelBeVisible(); + abstract protected boolean shouldPanelBeVisible(); /** * Updates the panel expansion and {@link PanelView} visibility if necessary. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index dba65d1cd233..cb0a1480c233 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -54,6 +54,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dock.DockManager; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.scrim.ScrimView; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.notification.stack.ViewState; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java index cee8b335f380..d37ecbc42168 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java @@ -23,6 +23,8 @@ import android.view.WindowManager; import com.android.systemui.assist.AssistManager; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationShadeWindowController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java index 50f21691b044..ebfbf54abe1a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.StatusBarState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index d250022102e9..f128a4124c94 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -55,6 +55,7 @@ import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.NotificationMediaManager; @@ -965,7 +966,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb @Override public boolean bouncerIsOrWillBeShowing() { - return isBouncerShowing() || mBouncer.getShowingSoon(); + return isBouncerShowing() || mBouncer.inTransit(); } public boolean isFullscreenBouncer() { @@ -1041,7 +1042,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } if (occluded != mLastOccluded || mFirstUpdate) { - mKeyguardUpdateManager.onKeyguardOccludedChanged(occluded); mKeyguardStateController.notifyKeyguardState(showing, occluded); } if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) { @@ -1070,11 +1070,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mCentralSurfaces.onKeyguardViewManagerStatesUpdated(); } - private View getCurrentNavBarView() { - final NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView(); - return navBarView != null ? navBarView.getCurrentView() : null; - } - /** * Updates the visibility of the nav bar window (which will cause insets changes). */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index cf776e3b60d1..451612ad4bb1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -52,21 +52,16 @@ import com.android.systemui.EventLogTags; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.assist.AssistManager; import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.NotificationClickNotifier; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.NotificationActivityStarter; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; -import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -92,24 +87,19 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte private final Context mContext; - private final CommandQueue mCommandQueue; private final Handler mMainThreadHandler; private final Executor mUiBgExecutor; - private final NotificationEntryManager mEntryManager; - private final NotifPipeline mNotifPipeline; private final NotificationVisibilityProvider mVisibilityProvider; private final HeadsUpManagerPhone mHeadsUpManager; private final ActivityStarter mActivityStarter; private final NotificationClickNotifier mClickNotifier; - private final StatusBarStateController mStatusBarStateController; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private final KeyguardManager mKeyguardManager; private final IDreamManager mDreamManager; private final Optional<BubblesManager> mBubblesManagerOptional; private final Lazy<AssistManager> mAssistManagerLazy; private final NotificationRemoteInputManager mRemoteInputManager; - private final GroupMembershipManager mGroupMembershipManager; private final NotificationLockscreenUserManager mLockscreenUserManager; private final ShadeController mShadeController; private final KeyguardStateController mKeyguardStateController; @@ -118,7 +108,6 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback; private final ActivityIntentHelper mActivityIntentHelper; - private final NotifPipelineFlags mNotifPipelineFlags; private final MetricsLogger mMetricsLogger; private final StatusBarNotificationActivityStarterLogger mLogger; @@ -134,23 +123,19 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte @Inject StatusBarNotificationActivityStarter( Context context, - CommandQueue commandQueue, Handler mainThreadHandler, Executor uiBgExecutor, - NotificationEntryManager entryManager, NotifPipeline notifPipeline, NotificationVisibilityProvider visibilityProvider, HeadsUpManagerPhone headsUpManager, ActivityStarter activityStarter, NotificationClickNotifier clickNotifier, - StatusBarStateController statusBarStateController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, KeyguardManager keyguardManager, IDreamManager dreamManager, Optional<BubblesManager> bubblesManagerOptional, Lazy<AssistManager> assistManagerLazy, NotificationRemoteInputManager remoteInputManager, - GroupMembershipManager groupMembershipManager, NotificationLockscreenUserManager lockscreenUserManager, ShadeController shadeController, KeyguardStateController keyguardStateController, @@ -158,7 +143,6 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte LockPatternUtils lockPatternUtils, StatusBarRemoteInputCallback remoteInputCallback, ActivityIntentHelper activityIntentHelper, - NotifPipelineFlags notifPipelineFlags, MetricsLogger metricsLogger, StatusBarNotificationActivityStarterLogger logger, OnUserInteractionCallback onUserInteractionCallback, @@ -168,23 +152,18 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte ActivityLaunchAnimator activityLaunchAnimator, NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) { mContext = context; - mCommandQueue = commandQueue; mMainThreadHandler = mainThreadHandler; mUiBgExecutor = uiBgExecutor; - mEntryManager = entryManager; - mNotifPipeline = notifPipeline; mVisibilityProvider = visibilityProvider; mHeadsUpManager = headsUpManager; mActivityStarter = activityStarter; mClickNotifier = clickNotifier; - mStatusBarStateController = statusBarStateController; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardManager = keyguardManager; mDreamManager = dreamManager; mBubblesManagerOptional = bubblesManagerOptional; mAssistManagerLazy = assistManagerLazy; mRemoteInputManager = remoteInputManager; - mGroupMembershipManager = groupMembershipManager; mLockscreenUserManager = lockscreenUserManager; mShadeController = shadeController; mKeyguardStateController = keyguardStateController; @@ -192,7 +171,6 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte mLockPatternUtils = lockPatternUtils; mStatusBarRemoteInputCallback = remoteInputCallback; mActivityIntentHelper = activityIntentHelper; - mNotifPipelineFlags = notifPipelineFlags; mMetricsLogger = metricsLogger; mLogger = logger; mOnUserInteractionCallback = onUserInteractionCallback; @@ -203,21 +181,12 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte mActivityLaunchAnimator = activityLaunchAnimator; mNotificationAnimationProvider = notificationAnimationProvider; - if (!mNotifPipelineFlags.isNewPipelineEnabled()) { - mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { - @Override - public void onPendingEntryAdded(NotificationEntry entry) { - handleFullScreenIntent(entry); - } - }); - } else { - mNotifPipeline.addCollectionListener(new NotifCollectionListener() { - @Override - public void onEntryAdded(NotificationEntry entry) { - handleFullScreenIntent(entry); - } - }); - } + notifPipeline.addCollectionListener(new NotifCollectionListener() { + @Override + public void onEntryAdded(NotificationEntry entry) { + handleFullScreenIntent(entry); + } + }); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index bd69cc3869c2..4bbd69b91a0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -30,19 +30,17 @@ import android.util.Log; import android.util.Slog; import android.view.View; import android.view.accessibility.AccessibilityManager; -import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.widget.MessagingGroup; -import com.android.internal.widget.MessagingMessage; -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.ForegroundServiceNotificationListener; import com.android.systemui.InitController; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; @@ -57,7 +55,6 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.AboveShelfObserver; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; @@ -72,16 +69,12 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent; import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; -import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import java.util.List; - import javax.inject.Inject; @CentralSurfacesComponent.CentralSurfacesScope class StatusBarNotificationPresenter implements NotificationPresenter, - ConfigurationController.ConfigurationListener, NotificationRowBinderImpl.BindRowCallback, CommandQueue.Callbacks { private static final String TAG = "StatusBarNotificationPresenter"; @@ -92,10 +85,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter, private final NotificationLockscreenUserManager mLockscreenUserManager; private final SysuiStatusBarStateController mStatusBarStateController; private final NotifShadeEventSource mNotifShadeEventSource; - private final NotificationEntryManager mEntryManager; private final NotificationMediaManager mMediaManager; private final NotificationGutsManager mGutsManager; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final LockscreenGestureLogger mLockscreenGestureLogger; private final NotificationPanelViewController mNotificationPanel; @@ -116,9 +107,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, private final IStatusBarService mBarService; private final DynamicPrivacyController mDynamicPrivacyController; private final NotificationListContainer mNotifListContainer; - private boolean mReinflateNotificationsOnUserSwitched; - private boolean mDispatchUiModeChangeOnUserSwitched; - private TextView mNotificationPanelDebugText; protected boolean mVrMode; @@ -143,15 +131,12 @@ class StatusBarNotificationPresenter implements NotificationPresenter, NotificationLockscreenUserManager lockscreenUserManager, SysuiStatusBarStateController sysuiStatusBarStateController, NotifShadeEventSource notifShadeEventSource, - NotificationEntryManager notificationEntryManager, NotificationMediaManager notificationMediaManager, NotificationGutsManager notificationGutsManager, - KeyguardUpdateMonitor keyguardUpdateMonitor, LockscreenGestureLogger lockscreenGestureLogger, InitController initController, NotificationInterruptStateProvider notificationInterruptStateProvider, NotificationRemoteInputManager remoteInputManager, - ConfigurationController configurationController, NotifPipelineFlags notifPipelineFlags, NotificationRemoteInputManager.Callback remoteInputManagerCallback, NotificationListContainer notificationListContainer) { @@ -170,10 +155,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter, mLockscreenUserManager = lockscreenUserManager; mStatusBarStateController = sysuiStatusBarStateController; mNotifShadeEventSource = notifShadeEventSource; - mEntryManager = notificationEntryManager; mMediaManager = notificationMediaManager; mGutsManager = notificationGutsManager; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; mLockscreenGestureLogger = lockscreenGestureLogger; mAboveShelfObserver = new AboveShelfObserver(stackScrollerController.getView()); mNotificationShadeWindowController = notificationShadeWindowController; @@ -208,11 +191,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, mNotifListContainer); mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied); mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse); - if (!mNotifPipelineFlags.isNewPipelineEnabled()) { - mEntryManager.setUpWithPresenter(this); - mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager); - mEntryManager.addNotificationLifetimeExtender(mGutsManager); - } notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor); mLockscreenUserManager.setUpWithPresenter(this); mMediaManager.setUpWithPresenter(this); @@ -225,7 +203,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, onUserSwitched(mLockscreenUserManager.getCurrentUserId()); }); - configurationController.addCallback(this); } /** Called when the shade has been emptied to attempt to close the shade */ @@ -240,65 +217,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, } @Override - public void onDensityOrFontScaleChanged() { - // TODO(b/145659174): Remove legacy pipeline code - if (mNotifPipelineFlags.isNewPipelineEnabled()) return; - MessagingMessage.dropCache(); - MessagingGroup.dropCache(); - if (!mKeyguardUpdateMonitor.isSwitchingUser()) { - updateNotificationsOnDensityOrFontScaleChanged(); - } else { - mReinflateNotificationsOnUserSwitched = true; - } - } - - @Override - public void onUiModeChanged() { - // TODO(b/145659174): Remove legacy pipeline code - if (mNotifPipelineFlags.isNewPipelineEnabled()) return; - if (!mKeyguardUpdateMonitor.isSwitchingUser()) { - updateNotificationsOnUiModeChanged(); - } else { - mDispatchUiModeChangeOnUserSwitched = true; - } - } - - @Override - public void onThemeChanged() { - onDensityOrFontScaleChanged(); - } - - private void updateNotificationsOnUiModeChanged() { - // TODO(b/145659174): Remove legacy pipeline code - if (mNotifPipelineFlags.isNewPipelineEnabled()) return; - List<NotificationEntry> userNotifications = - mEntryManager.getActiveNotificationsForCurrentUser(); - for (int i = 0; i < userNotifications.size(); i++) { - NotificationEntry entry = userNotifications.get(i); - ExpandableNotificationRow row = entry.getRow(); - if (row != null) { - row.onUiModeChanged(); - } - } - } - - private void updateNotificationsOnDensityOrFontScaleChanged() { - // TODO(b/145659174): Remove legacy pipeline code - if (mNotifPipelineFlags.isNewPipelineEnabled()) return; - List<NotificationEntry> userNotifications = - mEntryManager.getActiveNotificationsForCurrentUser(); - for (int i = 0; i < userNotifications.size(); i++) { - NotificationEntry entry = userNotifications.get(i); - entry.onDensityOrFontScaleChanged(); - boolean exposedGuts = entry.areGutsExposed(); - if (exposedGuts) { - mGutsManager.onDensityOrFontScaleChanged(entry); - } - } - } - - - @Override public boolean isCollapsing() { return mNotificationPanel.isCollapsing() || mNotificationShadeWindowController.isLaunchingActivity(); @@ -338,17 +256,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, // End old BaseStatusBar.userSwitched if (MULTIUSER_DEBUG) mNotificationPanel.setHeaderDebugInfo("USER " + newUserId); mCommandQueue.animateCollapsePanels(); - if (!mNotifPipelineFlags.isNewPipelineEnabled()) { - if (mReinflateNotificationsOnUserSwitched) { - updateNotificationsOnDensityOrFontScaleChanged(); - mReinflateNotificationsOnUserSwitched = false; - } - if (mDispatchUiModeChangeOnUserSwitched) { - updateNotificationsOnUiModeChanged(); - mDispatchUiModeChangeOnUserSwitched = false; - } - updateNotificationViews("user switched"); - } mMediaManager.clearCurrentMediaNotification(); mCentralSurfaces.setLockscreenUser(newUserId); updateMediaMetaData(true, false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java index 4e9090080c99..75dac1a093dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java @@ -136,8 +136,9 @@ public final class StatusBarTouchableRegionManager implements Dumpable { * Notify that the status bar panel gets expanded or collapsed. * * @param isExpanded True to notify expanded, false to notify collapsed. + * TODO(b/237811427) replace with a listener */ - void setPanelExpanded(boolean isExpanded) { + public void setPanelExpanded(boolean isExpanded) { if (isExpanded != mIsStatusBarExpanded) { mIsStatusBarExpanded = isExpanded; if (isExpanded) { @@ -153,7 +154,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable { * any existing display cutouts (notch) * @return the heads up notification touch area */ - Region calculateTouchableRegion() { + public Region calculateTouchableRegion() { // Update touchable region for HeadsUp notifications final Region headsUpTouchableRegion = mHeadsUpManager.getTouchableRegion(); if (headsUpTouchableRegion != null) { @@ -222,7 +223,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable { } } - void updateRegionForNotch(Region touchableRegion) { + public void updateRegionForNotch(Region touchableRegion) { WindowInsets windowInsets = mNotificationShadeWindowView.getRootWindowInsets(); if (windowInsets == null) { Log.w(TAG, "StatusBarWindowView is not attached."); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java index c5e5297ae6ba..84b279760f36 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java @@ -22,6 +22,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import com.android.keyguard.LockIconViewController; import com.android.systemui.biometrics.AuthRippleController; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationShelfController; import com.android.systemui.statusbar.core.StatusBarInitializer; @@ -33,9 +36,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks; import com.android.systemui.statusbar.phone.CentralSurfacesImpl; import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; -import com.android.systemui.statusbar.phone.NotificationShadeWindowView; -import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController; import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener; import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarterModule; import com.android.systemui.statusbar.phone.StatusBarNotificationPresenterModule; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java index 06532c4f9d17..41df8e3cbb31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java @@ -34,6 +34,10 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.privacy.OngoingPrivacyChip; +import com.android.systemui.shade.NotificationPanelView; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.NotificationShelfController; @@ -42,11 +46,8 @@ import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; +import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; import com.android.systemui.statusbar.phone.NotificationIconAreaController; -import com.android.systemui.statusbar.phone.NotificationPanelView; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; -import com.android.systemui.statusbar.phone.NotificationShadeWindowView; -import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; @@ -290,4 +291,17 @@ public abstract class StatusBarViewModule { secureSettings, mainExecutor); } + + /** + * Constructs a new, unattached {@link KeyguardBottomAreaView}. + * + * Note that this is explicitly _not_ a singleton, as we want to be able to reinflate it + */ + @Provides + public static KeyguardBottomAreaView providesKeyguardBottomAreaView( + NotificationPanelView npv, LayoutInflater layoutInflater) { + return (KeyguardBottomAreaView) layoutInflater.inflate(R + .layout.keyguard_bottom_area, npv, false); + } + } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index 597c949168d4..0e7da81f3b27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -48,6 +48,7 @@ import com.android.systemui.animation.Interpolators; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger.DisableState; import com.android.systemui.statusbar.OperatorNameView; @@ -59,7 +60,6 @@ import com.android.systemui.statusbar.connectivity.SignalCallback; import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.phone.NotificationIconAreaController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; import com.android.systemui.statusbar.phone.StatusBarIconController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java index d5f5362eaf3c..7252dfb76c14 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java @@ -21,8 +21,8 @@ import android.view.View; import com.android.systemui.R; import com.android.systemui.battery.BatteryMeterView; import com.android.systemui.dagger.qualifiers.RootView; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.HeadsUpStatusBarView; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions; import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.PhoneStatusBarViewController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java index a29ba916eb41..337ffdf46560 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java @@ -28,9 +28,9 @@ import android.widget.FrameLayout; import com.android.systemui.R; import com.android.systemui.settings.brightness.BrightnessSliderController; import com.android.systemui.settings.brightness.ToggleSlider; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.NotificationShadeDepthController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; -import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import java.util.Objects; import java.util.function.Consumer; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java index 2fb16ee9b3b9..bdac88837969 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java @@ -424,11 +424,6 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum } @Override - public void onFaceUnlockStateChanged(boolean running, int userId) { - update(false /* updateAlways */); - } - - @Override public void onStrongAuthStateChanged(int userId) { update(false /* updateAlways */); } diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java index c99ad23ab23d..fabbb2c1f44d 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java @@ -18,18 +18,20 @@ package com.android.systemui.tv; import android.content.Context; -import com.android.systemui.SystemUIFactory; +import com.android.systemui.SystemUIInitializer; import com.android.systemui.dagger.GlobalRootComponent; /** - * TV variant {@link SystemUIFactory}, that substitutes default {@link GlobalRootComponent} for + * TV variant {@link SystemUIInitializer}, that substitutes default {@link GlobalRootComponent} for * {@link TvGlobalRootComponent} */ -public class TvSystemUIFactory extends SystemUIFactory { +public class TvSystemUIInitializer extends SystemUIInitializer { + public TvSystemUIInitializer(Context context) { + super(context); + } + @Override - protected GlobalRootComponent buildGlobalRootComponent(Context context) { - return DaggerTvGlobalRootComponent.builder() - .context(context) - .build(); + protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() { + return DaggerTvGlobalRootComponent.builder(); } } diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java index 36a49af2276a..f1e89ac81b1b 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java @@ -46,6 +46,7 @@ import com.android.systemui.qs.dagger.QSModule; import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsImplementation; +import com.android.systemui.screenshot.ReferenceScreenshotModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -91,6 +92,7 @@ import dagger.multibindings.IntoSet; GestureModule.class, PowerModule.class, QSModule.class, + ReferenceScreenshotModule.class, VolumeModule.class, }, subcomponents = { diff --git a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt index 7350b37e4b66..13ac39c77c93 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt @@ -18,7 +18,7 @@ package com.android.systemui.unfold import com.android.keyguard.KeyguardUnfoldTransition import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.phone.NotificationPanelUnfoldAnimationController +import com.android.systemui.shade.NotificationPanelUnfoldAnimationController import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt index ad734914170b..74d51112deeb 100644 --- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt @@ -28,6 +28,7 @@ import android.os.Bundle import android.os.UserManager import android.provider.Settings import android.view.LayoutInflater +import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.widget.AdapterView @@ -38,8 +39,10 @@ import androidx.constraintlayout.helper.widget.Flow import com.android.internal.annotations.VisibleForTesting import com.android.internal.util.UserIcons import com.android.settingslib.Utils +import com.android.systemui.Gefingerpoken import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.FalsingManager.LOW_PENALTY import com.android.systemui.settings.UserTracker @@ -61,12 +64,13 @@ class UserSwitcherActivity @Inject constructor( private val userSwitcherController: UserSwitcherController, private val broadcastDispatcher: BroadcastDispatcher, private val layoutInflater: LayoutInflater, + private val falsingCollector: FalsingCollector, private val falsingManager: FalsingManager, private val userManager: UserManager, private val userTracker: UserTracker ) : LifecycleActivity() { - private lateinit var parent: ViewGroup + private lateinit var parent: UserSwitcherRootView private lateinit var broadcastReceiver: BroadcastReceiver private var popupMenu: UserSwitcherPopupMenu? = null private lateinit var addButton: View @@ -202,7 +206,14 @@ class UserSwitcherActivity @Inject constructor( or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) - parent = requireViewById<ViewGroup>(R.id.user_switcher_root) + parent = requireViewById<UserSwitcherRootView>(R.id.user_switcher_root) + + parent.touchHandler = object : Gefingerpoken { + override fun onTouchEvent(ev: MotionEvent?): Boolean { + falsingCollector.onTouchEvent(ev) + return false + } + } requireViewById<View>(R.id.cancel).apply { setOnClickListener { @@ -241,7 +252,7 @@ class UserSwitcherActivity @Inject constructor( ) popupMenuAdapter.addAll(items) - popupMenu = UserSwitcherPopupMenu(this, falsingManager).apply { + popupMenu = UserSwitcherPopupMenu(this).apply { setAnchorView(addButton) setAdapter(popupMenuAdapter) setOnItemClickListener { diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt index 754a9342bfb0..ee785b62bd50 100644 --- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt +++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt @@ -23,16 +23,13 @@ import android.view.View.MeasureSpec import android.widget.ListAdapter import android.widget.ListPopupWindow import android.widget.ListView - import com.android.systemui.R -import com.android.systemui.plugins.FalsingManager /** * Popup menu for displaying items on the fullscreen user switcher. */ class UserSwitcherPopupMenu( - private val context: Context, - private val falsingManager: FalsingManager + private val context: Context ) : ListPopupWindow(context) { private val res = context.resources diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt new file mode 100644 index 000000000000..66a301744025 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.constraintlayout.widget.ConstraintLayout +import com.android.systemui.Gefingerpoken + +/** A simple subclass that allows for observing touch events as they happen. */ +class UserSwitcherRootView( + context: Context, + attrs: AttributeSet? +) : ConstraintLayout(context, attrs) { + + /** Assign this field to observer touch events. */ + var touchHandler: Gefingerpoken? = null + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + touchHandler?.onTouchEvent(ev) + return super.dispatchTouchEvent(ev) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/util/InitializationChecker.kt b/packages/SystemUI/src/com/android/systemui/util/InitializationChecker.kt new file mode 100644 index 000000000000..f53b6824d45d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/InitializationChecker.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util + +import android.app.ActivityThread +import android.os.Process +import com.android.systemui.dagger.qualifiers.InstrumentationTest +import javax.inject.Inject + +/** + * Used to check whether SystemUI should be fully initialized. + */ +class InitializationChecker @Inject constructor( + @InstrumentationTest private val instrumentationTest: Boolean +) { + + /** + * Only initialize components for the main system ui process running as the primary user + */ + fun initializeComponents(): Boolean = + !instrumentationTest && + Process.myUserHandle().isSystem && + ActivityThread.currentProcessName() == ActivityThread.currentPackageName() +} diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt new file mode 100644 index 000000000000..05d087e232ba --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt @@ -0,0 +1,41 @@ +package com.android.systemui.util.kotlin + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.dagger.qualifiers.Main +import dagger.Module +import dagger.Provides +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers + +/** Providers for various coroutines-related constructs. */ +@Module +object CoroutinesModule { + @Provides + @SysUISingleton + @Application + fun applicationScope( + @Main dispatcher: CoroutineDispatcher, + ): CoroutineScope = CoroutineScope(dispatcher) + + @Provides + @SysUISingleton + @Main + fun mainDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate + + /** + * Provide a [CoroutineDispatcher] backed by a thread pool containing at most X threads, where + * X is the number of CPU cores available. + * + * Because there are multiple threads at play, there is no serialization order guarantee. You + * should use a [kotlinx.coroutines.channels.Channel] for serialization if necessary. + * + * @see Dispatchers.Default + */ + @Provides + @SysUISingleton + @Background + fun bgDispatcher(): CoroutineDispatcher = Dispatchers.Default +} diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java index bca2a24ff12d..e08a9d022fb9 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java @@ -72,7 +72,6 @@ import com.android.systemui.statusbar.notification.collection.render.Notificatio import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; -import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.wm.shell.bubbles.Bubble; @@ -126,7 +125,6 @@ public class BubblesManager implements Dumpable { NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, ShadeController shadeController, - ConfigurationController configurationController, @Nullable IStatusBarService statusBarService, INotificationManager notificationManager, NotificationVisibilityProvider visibilityProvider, @@ -145,7 +143,6 @@ public class BubblesManager implements Dumpable { notificationShadeWindowController, keyguardStateController, shadeController, - configurationController, statusBarService, notificationManager, visibilityProvider, @@ -169,7 +166,6 @@ public class BubblesManager implements Dumpable { NotificationShadeWindowController notificationShadeWindowController, KeyguardStateController keyguardStateController, ShadeController shadeController, - ConfigurationController configurationController, @Nullable IStatusBarService statusBarService, INotificationManager notificationManager, NotificationVisibilityProvider visibilityProvider, @@ -213,23 +209,6 @@ public class BubblesManager implements Dumpable { } }); - configurationController.addCallback(new ConfigurationController.ConfigurationListener() { - @Override - public void onConfigChanged(Configuration newConfig) { - mBubbles.onConfigChanged(newConfig); - } - - @Override - public void onUiModeChanged() { - mBubbles.updateForThemeChanges(); - } - - @Override - public void onThemeChanged() { - mBubbles.updateForThemeChanges(); - } - }); - zenModeController.addCallback(new ZenModeController.Callback() { @Override public void onZenChanged(int zen) { diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index a6db2aa48a88..fa2af56743c6 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -47,7 +47,6 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.model.SysUiState; -import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.shared.tracing.ProtoTraceable; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -67,6 +66,7 @@ import com.android.wm.shell.onehanded.OneHandedUiEventLogger; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.protolog.ShellProtoLogImpl; import com.android.wm.shell.splitscreen.SplitScreen; +import com.android.wm.shell.sysui.ShellInterface; import java.io.PrintWriter; import java.util.Arrays; @@ -106,6 +106,7 @@ public final class WMShell extends CoreStartable | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; // Shell interfaces + private final ShellInterface mShell; private final Optional<Pip> mPipOptional; private final Optional<SplitScreen> mSplitScreenOptional; private final Optional<OneHanded> mOneHandedOptional; @@ -118,7 +119,6 @@ public final class WMShell extends CoreStartable private final ConfigurationController mConfigurationController; private final KeyguardStateController mKeyguardStateController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final NavigationModeController mNavigationModeController; private final ScreenLifecycle mScreenLifecycle; private final SysUiState mSysUiState; private final WakefulnessLifecycle mWakefulnessLifecycle; @@ -135,6 +135,7 @@ public final class WMShell extends CoreStartable @Inject public WMShell(Context context, + ShellInterface shell, Optional<Pip> pipOptional, Optional<SplitScreen> splitScreenOptional, Optional<OneHanded> oneHandedOptional, @@ -146,7 +147,6 @@ public final class WMShell extends CoreStartable ConfigurationController configurationController, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, - NavigationModeController navigationModeController, ScreenLifecycle screenLifecycle, SysUiState sysUiState, ProtoTracer protoTracer, @@ -154,11 +154,11 @@ public final class WMShell extends CoreStartable UserInfoController userInfoController, @Main Executor sysUiMainExecutor) { super(context); + mShell = shell; mCommandQueue = commandQueue; mConfigurationController = configurationController; mKeyguardStateController = keyguardStateController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mNavigationModeController = navigationModeController; mScreenLifecycle = screenLifecycle; mSysUiState = sysUiState; mPipOptional = pipOptional; @@ -176,6 +176,15 @@ public final class WMShell extends CoreStartable @Override public void start() { + // Notify with the initial configuration and subscribe for new config changes + mShell.onConfigurationChanged(mContext.getResources().getConfiguration()); + mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() { + @Override + public void onConfigChanged(Configuration newConfig) { + mShell.onConfigurationChanged(newConfig); + } + }); + // TODO: Consider piping config change and other common calls to a shell component to // delegate internally mProtoTracer.add(this); @@ -183,9 +192,7 @@ public final class WMShell extends CoreStartable mPipOptional.ifPresent(this::initPip); mSplitScreenOptional.ifPresent(this::initSplitScreen); mOneHandedOptional.ifPresent(this::initOneHanded); - mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout); mCompatUIOptional.ifPresent(this::initCompatUi); - mDragAndDropOptional.ifPresent(this::initDragAndDrop); } @VisibleForTesting @@ -216,23 +223,6 @@ public final class WMShell extends CoreStartable pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag); }); - mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() { - @Override - public void onConfigChanged(Configuration newConfig) { - pip.onConfigurationChanged(newConfig); - } - - @Override - public void onDensityOrFontScaleChanged() { - pip.onDensityOrFontScaleChanged(); - } - - @Override - public void onThemeChanged() { - pip.onOverlayChanged(); - } - }); - // The media session listener needs to be re-registered when switching users mUserInfoController.addCallback((String name, Drawable picture, String userAccount) -> pip.registerSessionListenerForCurrentUser()); @@ -348,23 +338,6 @@ public final class WMShell extends CoreStartable } } }); - - mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() { - @Override - public void onConfigChanged(Configuration newConfig) { - oneHanded.onConfigChanged(newConfig); - } - }); - } - - @VisibleForTesting - void initHideDisplayCutout(HideDisplayCutout hideDisplayCutout) { - mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() { - @Override - public void onConfigChanged(Configuration newConfig) { - hideDisplayCutout.onConfigurationChanged(newConfig); - } - }); } @VisibleForTesting @@ -378,20 +351,6 @@ public final class WMShell extends CoreStartable mKeyguardStateController.addCallback(mCompatUIKeyguardCallback); } - void initDragAndDrop(DragAndDrop dragAndDrop) { - mConfigurationController.addCallback(new ConfigurationController.ConfigurationListener() { - @Override - public void onConfigChanged(Configuration newConfig) { - dragAndDrop.onConfigChanged(newConfig); - } - - @Override - public void onThemeChanged() { - dragAndDrop.onThemeChanged(); - } - }); - } - @Override public void writeToProto(SystemUiTraceProto proto) { if (proto.wmShell == null) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java index ac1a83c269e0..4021652295c1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +32,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableResources; import android.view.Gravity; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -42,6 +44,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -104,6 +107,17 @@ public class KeyguardHostViewControllerTest extends SysuiTestCase { } @Test + public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() { + mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE); + mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE); + + InOrder order = inOrder(mKeyguardSecurityContainerController); + order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE); + order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged( + View.INVISIBLE); + } + + @Test public void testGravityReappliedOnConfigurationChange() { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt index b1e2012ecd40..ad6d146fb5f3 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt @@ -92,7 +92,6 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel( keyguardAwake = false, keyguardGoingAway = false, listeningForFaceAssistant = false, - lockIconPressed = false, occludingAppRequestingFaceAuth = false, primaryUser = false, scanningAllowedByStrongAuth = false, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index bc351427310d..68e49c0a1d4b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -25,17 +25,21 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Configuration; import android.content.res.Resources; +import android.hardware.biometrics.BiometricSourceType; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.View; import android.view.WindowInsetsController; import androidx.test.filters.SmallTest; @@ -46,6 +50,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.biometrics.SidefpsController; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.log.SessionTracker; @@ -59,10 +64,14 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Optional; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper() @@ -124,6 +133,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { private SessionTracker mSessionTracker; @Mock private KeyguardViewController mKeyguardViewController; + @Mock + private SidefpsController mSidefpsController; + @Mock + private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock; + + @Captor + private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback; + private Configuration mConfiguration; private KeyguardSecurityContainerController mKeyguardSecurityContainerController; @@ -160,7 +177,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardStateController, mKeyguardSecurityViewFlipperController, mConfigurationController, mFalsingCollector, mFalsingManager, mUserSwitcherController, mFeatureFlags, mGlobalSettings, - mSessionTracker).create(mSecurityCallback); + mSessionTracker, Optional.of(mSidefpsController)).create(mSecurityCallback); } @Test @@ -258,9 +275,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Test public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() { when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true); - when(mKeyguardSecurityViewFlipperController.getSecurityView( - eq(SecurityMode.Password), any(KeyguardSecurityCallback.class))) - .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController); + setupGetSecurityView(); mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password); verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager, @@ -276,4 +291,126 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { verify(mUserSwitcherController) .removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class)); } + + @Test + public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() { + setupConditionsToEnableSideFpsHint(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).show(); + verify(mSidefpsController, never()).hide(); + } + + @Test + public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() { + setupConditionsToEnableSideFpsHint(); + setFingerprintDetectionRunning(false); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() { + setupConditionsToEnableSideFpsHint(); + setSidedSecurityMode(false); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() { + setupConditionsToEnableSideFpsHint(); + setNeedsStrongAuth(true); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + verify(mSidefpsController, atLeastOnce()).show(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + verify(mSidefpsController, atLeastOnce()).show(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onStartingToHide(); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onPause_sideFpsHintShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + verify(mSidefpsController, atLeastOnce()).show(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onPause(); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + private void setupConditionsToEnableSideFpsHint() { + attachView(); + setSidedSecurityMode(true); + setFingerprintDetectionRunning(true); + setNeedsStrongAuth(false); + } + + private void attachView() { + mKeyguardSecurityContainerController.onViewAttached(); + verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture()); + } + + private void setFingerprintDetectionRunning(boolean running) { + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running); + mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running, + BiometricSourceType.FINGERPRINT); + } + + private void setSidedSecurityMode(boolean sided) { + when(mView.isSidedSecurityMode()).thenReturn(sided); + } + + private void setNeedsStrongAuth(boolean needed) { + when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed); + mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0); + } + + private void setupGetSecurityView() { + when(mKeyguardSecurityViewFlipperController.getSecurityView( + any(), any(KeyguardSecurityCallback.class))) + .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewControllerMock); + } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 2dc066c8a9db..84903d17852f 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -1109,8 +1109,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { // THEN face unlock is not running b/c status bar state changes don't cause biometric // listening state to update - assertThat(mKeyguardUpdateMonitor.isFaceUnlockRunning( - KeyguardUpdateMonitor.getCurrentUser())).isEqualTo(false); + assertThat(mKeyguardUpdateMonitor.isFaceDetectionRunning()).isEqualTo(false); // WHEN biometric listening state is updated mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java index 5d8e4351cfd9..a0fdc8f1555e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java @@ -26,6 +26,8 @@ import com.android.systemui.statusbar.policy.FlashlightController; import org.junit.Assert; import org.junit.Test; +import java.util.concurrent.ExecutionException; + @SmallTest public class DependencyTest extends SysuiTestCase { @@ -44,10 +46,12 @@ public class DependencyTest extends SysuiTestCase { } @Test - public void testInitDependency() { + public void testInitDependency() throws ExecutionException, InterruptedException { Dependency.clearDependencies(); - Dependency dependency = - SystemUIFactory.getInstance().getSysUIComponent().createDependency(); + SystemUIInitializer initializer = + SystemUIInitializerFactory.createFromConfigNoAssert(mContext); + initializer.init(true); + Dependency dependency = initializer.getSysUIComponent().createDependency(); dependency.start(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java index 8c20b248d02c..9179efc9f39f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java @@ -34,6 +34,8 @@ import org.junit.Before; import org.junit.Rule; import org.mockito.Mockito; +import java.util.concurrent.ExecutionException; + public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { public static final Class<?>[] ALL_SUPPORTED_CLASSES = LeakCheckedTest.ALL_SUPPORTED_CLASSES; @@ -54,10 +56,11 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { } @Before - public void SysuiSetup() { - SystemUIFactory.createFromConfig(mContext, true); - mDependency = new TestableDependency( - SystemUIFactory.getInstance().getSysUIComponent().createDependency()); + public void sysuiSetup() throws ExecutionException, InterruptedException { + SystemUIInitializer initializer = + SystemUIInitializerFactory.createFromConfigNoAssert(mContext); + initializer.init(true); + mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency()); Dependency.setInstance(mDependency); // TODO: Figure out another way to give reference to a SysuiTestableContext. @@ -77,7 +80,6 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { public void SysuiTeardown() { InstrumentationRegistry.registerInstance(mRealInstrumentation, InstrumentationRegistry.getArguments()); - SystemUIFactory.cleanup(); } @AfterClass diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java index 8c7927782d2d..c52ea60f0bfc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java @@ -76,9 +76,10 @@ public abstract class SysuiTestCase { @Before public void SysuiSetup() throws Exception { - SystemUIFactory.createFromConfig(mContext, true); - mDependency = new TestableDependency( - SystemUIFactory.getInstance().getSysUIComponent().createDependency()); + SystemUIInitializer initializer = + SystemUIInitializerFactory.createFromConfigNoAssert(mContext); + initializer.init(true); + mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency()); Dependency.setInstance(mDependency); mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class), mock(Executor.class), mock(DumpManager.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt index b61fbbe1ea75..273786d74782 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt @@ -207,25 +207,30 @@ ViewHierarchyAnimatorTest : SysuiTestCase() { } @Test - fun animatesAppearingViewsFromStartToEnd() { - // Starting GONE. - rootView.visibility = View.GONE - rootView.layout(0 /* l */, 50 /* t */, 50 /* r */, 100 /* b */) - var success = ViewHierarchyAnimator.animateAddition(rootView) - rootView.visibility = View.VISIBLE - rootView.layout(0 /* l */, 100 /* t */, 100 /* r */, 200 /* b */) + fun animatesInvisibleViews() { + rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */) + rootView.visibility = View.INVISIBLE + + val success = ViewHierarchyAnimator.animate(rootView) + // Change all bounds. + rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */) assertTrue(success) assertNotNull(rootView.getTag(R.id.tag_animator)) - checkBounds(rootView, l = 50, t = 150, r = 50, b = 150) + // The initial values should be those of the previous layout. + checkBounds(rootView, l = 10, t = 10, r = 50, b = 50) endAnimation(rootView) assertNull(rootView.getTag(R.id.tag_animator)) - checkBounds(rootView, l = 0, t = 100, r = 100, b = 200) + // The end values should be those of the latest layout. + checkBounds(rootView, l = 0, t = 15, r = 70, b = 80) + } - // Starting INVISIBLE. - rootView.visibility = View.INVISIBLE + @Test + fun animatesAppearingViewsFromStartToEnd() { + // Starting GONE. + rootView.visibility = View.GONE rootView.layout(0 /* l */, 50 /* t */, 50 /* r */, 100 /* b */) - success = ViewHierarchyAnimator.animateAddition(rootView) + var success = ViewHierarchyAnimator.animateAddition(rootView) rootView.visibility = View.VISIBLE rootView.layout(0 /* l */, 100 /* t */, 100 /* r */, 200 /* b */) @@ -937,7 +942,7 @@ ViewHierarchyAnimatorTest : SysuiTestCase() { } @Test - fun doesNotAnimateInvisibleViews() { + fun doesNotAnimateGoneViews() { rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */) // GONE @@ -948,15 +953,6 @@ ViewHierarchyAnimatorTest : SysuiTestCase() { assertFalse(success) assertNull(rootView.getTag(R.id.tag_animator)) checkBounds(rootView, l = 0, t = 15, r = 55, b = 80) - - // INVISIBLE. - rootView.visibility = View.INVISIBLE - success = ViewHierarchyAnimator.animate(rootView) - rootView.layout(0 /* l */, 20 /* t */, 10 /* r */, 50 /* b */) - - assertFalse(success) - assertNull(rootView.getTag(R.id.tag_animator)) - checkBounds(rootView, l = 0, t = 20, r = 10, b = 50) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index bc0d76e4a101..bf3788e4c76a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -48,11 +48,12 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.anyInt +import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.Mockito.never import org.mockito.Mockito.verify -import org.mockito.junit.MockitoJUnit import org.mockito.Mockito.`when` as whenever +import org.mockito.junit.MockitoJUnit @RunWith(AndroidTestingRunner::class) @RunWithLooper(setAsMainLooper = true) @@ -87,7 +88,7 @@ class AuthContainerViewTest : SysuiTestCase() { @Test fun testNotifiesAnimatedIn() { initializeFingerprintContainer() - verify(callback).onDialogAnimatedIn() + verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L) } @Test @@ -96,13 +97,13 @@ class AuthContainerViewTest : SysuiTestCase() { container.dismissFromSystemServer() waitForIdleSync() - verify(callback, never()).onDialogAnimatedIn() + verify(callback, never()).onDialogAnimatedIn(anyLong()) container.addToView() waitForIdleSync() // attaching the view resets the state and allows this to happen again - verify(callback).onDialogAnimatedIn() + verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L) } @Test @@ -110,14 +111,17 @@ class AuthContainerViewTest : SysuiTestCase() { val container = initializeFingerprintContainer() waitForIdleSync() - verify(callback).onDialogAnimatedIn() + val requestID = authContainer?.requestId ?: 0L + + verify(callback).onDialogAnimatedIn(requestID) container.onWindowFocusChanged(false) waitForIdleSync() verify(callback).onDismissed( - eq(AuthDialogCallback.DISMISSED_USER_CANCELED), - eq<ByteArray?>(null) /* credentialAttestation */ + eq(AuthDialogCallback.DISMISSED_USER_CANCELED), + eq<ByteArray?>(null), /* credentialAttestation */ + eq(requestID) ) assertThat(container.parent).isNull() } @@ -131,8 +135,9 @@ class AuthContainerViewTest : SysuiTestCase() { waitForIdleSync() verify(callback).onDismissed( - eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED), - eq<ByteArray?>(null) /* credentialAttestation */ + eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED), + eq<ByteArray?>(null), /* credentialAttestation */ + eq(authContainer?.requestId ?: 0L) ) assertThat(container.parent).isNull() } @@ -146,11 +151,13 @@ class AuthContainerViewTest : SysuiTestCase() { waitForIdleSync() verify(callback).onSystemEvent( - eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL) + eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL), + eq(authContainer?.requestId ?: 0L) ) verify(callback).onDismissed( - eq(AuthDialogCallback.DISMISSED_USER_CANCELED), - eq<ByteArray?>(null) /* credentialAttestation */ + eq(AuthDialogCallback.DISMISSED_USER_CANCELED), + eq<ByteArray?>(null), /* credentialAttestation */ + eq(authContainer?.requestId ?: 0L) ) assertThat(container.parent).isNull() } @@ -164,8 +171,9 @@ class AuthContainerViewTest : SysuiTestCase() { waitForIdleSync() verify(callback).onDismissed( - eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE), - eq<ByteArray?>(null) /* credentialAttestation */ + eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE), + eq<ByteArray?>(null), /* credentialAttestation */ + eq(authContainer?.requestId ?: 0L) ) assertThat(container.parent).isNull() } @@ -180,7 +188,7 @@ class AuthContainerViewTest : SysuiTestCase() { ) waitForIdleSync() - verify(callback).onTryAgainPressed() + verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L) } @Test @@ -192,8 +200,9 @@ class AuthContainerViewTest : SysuiTestCase() { waitForIdleSync() verify(callback).onDismissed( - eq(AuthDialogCallback.DISMISSED_ERROR), - eq<ByteArray?>(null) /* credentialAttestation */ + eq(AuthDialogCallback.DISMISSED_ERROR), + eq<ByteArray?>(null), /* credentialAttestation */ + eq(authContainer?.requestId ?: 0L) ) assertThat(authContainer!!.parent).isNull() } @@ -209,7 +218,7 @@ class AuthContainerViewTest : SysuiTestCase() { ) waitForIdleSync() - verify(callback).onDeviceCredentialPressed() + verify(callback).onDeviceCredentialPressed(authContainer?.requestId ?: 0L) assertThat(container.hasCredentialView()).isTrue() } @@ -322,12 +331,12 @@ class AuthContainerViewTest : SysuiTestCase() { container.onAuthenticationFailed(BiometricAuthenticator.TYPE_FACE, "failed") waitForIdleSync() - verify(callback, never()).onTryAgainPressed() + verify(callback, never()).onTryAgainPressed(anyLong()) container.onPointerDown() waitForIdleSync() - verify(callback).onTryAgainPressed() + verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L) } private fun initializeFingerprintContainer( diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index d948a99f8ad8..d158892e4ec5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -291,7 +291,8 @@ public class AuthControllerTest extends SysuiTestCase { public void testSendsReasonUserCanceled_whenDismissedByUserCancel() throws Exception { showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, - null /* credentialAttestation */); + null, /* credentialAttestation */ + mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL), eq(null) /* credentialAttestation */); @@ -301,7 +302,8 @@ public class AuthControllerTest extends SysuiTestCase { public void testSendsReasonNegative_whenDismissedByButtonNegative() throws Exception { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE, - null /* credentialAttestation */); + null, /* credentialAttestation */ + mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_NEGATIVE), eq(null) /* credentialAttestation */); @@ -311,7 +313,8 @@ public class AuthControllerTest extends SysuiTestCase { public void testSendsReasonConfirmed_whenDismissedByButtonPositive() throws Exception { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE, - null /* credentialAttestation */); + null, /* credentialAttestation */ + mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED), eq(null) /* credentialAttestation */); @@ -321,7 +324,8 @@ public class AuthControllerTest extends SysuiTestCase { public void testSendsReasonConfirmNotRequired_whenDismissedByAuthenticated() throws Exception { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED, - null /* credentialAttestation */); + null, /* credentialAttestation */ + mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED), eq(null) /* credentialAttestation */); @@ -331,7 +335,8 @@ public class AuthControllerTest extends SysuiTestCase { public void testSendsReasonError_whenDismissedByError() throws Exception { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_ERROR, - null /* credentialAttestation */); + null, /* credentialAttestation */ + mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_ERROR), eq(null) /* credentialAttestation */); @@ -341,7 +346,8 @@ public class AuthControllerTest extends SysuiTestCase { public void testSendsReasonServerRequested_whenDismissedByServer() throws Exception { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER, - null /* credentialAttestation */); + null, /* credentialAttestation */ + mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED), eq(null) /* credentialAttestation */); @@ -355,7 +361,7 @@ public class AuthControllerTest extends SysuiTestCase { final byte[] credentialAttestation = generateRandomHAT(); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED, - credentialAttestation); + credentialAttestation, mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED), AdditionalMatchers.aryEq(credentialAttestation)); @@ -531,7 +537,7 @@ public class AuthControllerTest extends SysuiTestCase { final byte[] credentialAttestation = generateRandomHAT(); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED, - credentialAttestation); + credentialAttestation, mAuthController.mCurrentDialog.getRequestId()); verify(mReceiver).onDialogDismissed( eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED), AdditionalMatchers.aryEq(credentialAttestation)); @@ -640,17 +646,19 @@ public class AuthControllerTest extends SysuiTestCase { @Test public void testDoesNotCrash_whenTryAgainPressedAfterDismissal() { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); + final long requestID = mAuthController.mCurrentDialog.getRequestId(); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, - null /* credentialAttestation */); - mAuthController.onTryAgainPressed(); + null, /* credentialAttestation */requestID); + mAuthController.onTryAgainPressed(requestID); } @Test public void testDoesNotCrash_whenDeviceCredentialPressedAfterDismissal() { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); + final long requestID = mAuthController.mCurrentDialog.getRequestId(); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, - null /* credentialAttestation */); - mAuthController.onDeviceCredentialPressed(); + null /* credentialAttestation */, requestID); + mAuthController.onDeviceCredentialPressed(requestID); } @Test @@ -708,7 +716,8 @@ public class AuthControllerTest extends SysuiTestCase { // WHEN dialog is shown and then dismissed showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */); mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED, - null /* credentialAttestation */); + null /* credentialAttestation */, + mAuthController.mCurrentDialog.getRequestId()); // THEN callback should be received verify(callback).onBiometricPromptDismissed(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS new file mode 100644 index 000000000000..adb10f01b5e1 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS @@ -0,0 +1,4 @@ +set noparent + +include /services/core/java/com/android/server/biometrics/OWNERS +beverlyt@google.com diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt index dec2b82ed88f..6157ccbd597a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt @@ -62,7 +62,6 @@ import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.eq import org.mockito.Captor import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.any import org.mockito.Mockito.anyFloat import org.mockito.Mockito.anyInt @@ -72,6 +71,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenEver import org.mockito.junit.MockitoJUnit private const val DISPLAY_ID = 2 @@ -126,15 +126,15 @@ class SidefpsControllerTest : SysuiTestCase() { context.addMockSystemService(DisplayManager::class.java, displayManager) context.addMockSystemService(WindowManager::class.java, windowManager) - `when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView) - `when`(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation))) + whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView) + whenEver(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation))) .thenReturn(mock(LottieAnimationView::class.java)) with(mock(ViewPropertyAnimator::class.java)) { - `when`(sidefpsView.animate()).thenReturn(this) - `when`(alpha(anyFloat())).thenReturn(this) - `when`(setStartDelay(anyLong())).thenReturn(this) - `when`(setDuration(anyLong())).thenReturn(this) - `when`(setListener(any())).thenAnswer { + whenEver(sidefpsView.animate()).thenReturn(this) + whenEver(alpha(anyFloat())).thenReturn(this) + whenEver(setStartDelay(anyLong())).thenReturn(this) + whenEver(setDuration(anyLong())).thenReturn(this) + whenEver(setListener(any())).thenAnswer { (it.arguments[0] as Animator.AnimatorListener) .onAnimationEnd(mock(Animator::class.java)) this @@ -177,7 +177,7 @@ class SidefpsControllerTest : SysuiTestCase() { displayBounds = Rect(0, 0, displayWidth, displayHeight) var locations = listOf(sensorLocation) - `when`(fingerprintManager.sensorPropertiesInternal).thenReturn( + whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn( listOf( FingerprintSensorPropertiesInternal( SENSOR_ID, @@ -196,12 +196,12 @@ class SidefpsControllerTest : SysuiTestCase() { displayInfo.initInfo() val dmGlobal = mock(DisplayManagerGlobal::class.java) val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS) - `when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo) - `when`(windowManager.defaultDisplay).thenReturn(display) - `when`(windowManager.maximumWindowMetrics).thenReturn( + whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo) + whenEver(windowManager.defaultDisplay).thenReturn(display) + whenEver(windowManager.maximumWindowMetrics).thenReturn( WindowMetrics(displayBounds, WindowInsets.CONSUMED) ) - `when`(windowManager.currentWindowMetrics).thenReturn( + whenEver(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(displayBounds, windowInsets) ) @@ -277,13 +277,13 @@ class SidefpsControllerTest : SysuiTestCase() { @Test fun testShowsForMostSettings() = testWithDisplay { - `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask())) + whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask())) testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false) } @Test fun testIgnoredForVerySpecificSettings() = testWithDisplay { - `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask())) + whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask())) testIgnoredFor(REASON_AUTH_SETTINGS) } @@ -424,6 +424,20 @@ class SidefpsControllerTest : SysuiTestCase() { assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth) assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY) } + + @Test + fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay { + // By default all those tests assume the side fps sensor is available. + + assertThat(fingerprintManager.hasSideFpsSensor()).isTrue() + } + + @Test + fun hasSideFpsSensor_withoutSensorProps_returnsFalse() { + whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null) + + assertThat(fingerprintManager.hasSideFpsSensor()).isFalse() + } } private fun insetsForSmallNavbar() = insetsWithBottom(60) diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java index e5a75e231f8d..49cdfa72f344 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java @@ -86,7 +86,7 @@ public class DozeUiTest extends SysuiTestCase { mHandler = mHandlerThread.getThreadHandler(); mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler, - mDozeParameters, mKeyguardUpdateMonitor, mStatusBarStateController, mDozeLog); + mDozeParameters, mStatusBarStateController, mDozeLog); mDozeUi.setDozeMachine(mMachine); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java index d334694805fe..60e5a9423c61 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java @@ -184,25 +184,36 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase { } @Test - public void testOnViewAttachedShowsMicCameraIconWhenDisabled() { + public void testOnViewAttachedShowsMicIconWhenDisabled() { when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE)) .thenReturn(true); when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA)) - .thenReturn(true); + .thenReturn(false); mController.onViewAttached(); verify(mView).showIcon( - DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, true, null); + DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED, true, null); } @Test - public void testOnViewAttachedHidesMicCameraIconWhenEnabled() { + public void testOnViewAttachedShowsCameraIconWhenDisabled() { when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE)) .thenReturn(false); when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA)) - .thenReturn(false); + .thenReturn(true); + mController.onViewAttached(); + verify(mView).showIcon( + DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED, true, null); + } + + @Test + public void testOnViewAttachedShowsMicCameraIconWhenDisabled() { + when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE)) + .thenReturn(true); + when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA)) + .thenReturn(true); mController.onViewAttached(); verify(mView).showIcon( - DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false, null); + DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, true, null); } @Test @@ -386,24 +397,6 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase { } @Test - public void testMicCameraIconHiddenWhenSensorsNotBlocked() { - when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE)) - .thenReturn(true).thenReturn(false); - when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA)) - .thenReturn(true).thenReturn(false); - mController.onViewAttached(); - - final ArgumentCaptor<IndividualSensorPrivacyController.Callback> callbackCapture = - ArgumentCaptor.forClass(IndividualSensorPrivacyController.Callback.class); - verify(mSensorPrivacyController).addCallback(callbackCapture.capture()); - callbackCapture.getValue().onSensorBlockedChanged( - SensorPrivacyManager.Sensors.MICROPHONE, false); - - verify(mView).showIcon( - DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false, null); - } - - @Test public void testPriorityModeIconShownWhenZenModeEnabled() { mController.onViewAttached(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java index 883bec465815..a23c4b50082f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.content.Context; +import android.content.res.Resources; import android.testing.AndroidTestingRunner; import android.widget.TextView; @@ -79,7 +80,7 @@ public class DreamWeatherComplicationTest extends SysuiTestCase { final DreamWeatherComplication.DreamWeatherViewController controller = new DreamWeatherComplication.DreamWeatherViewController(mock( TextView.class), TRAMPOLINE_COMPONENT, mock(ActivityStarter.class), - mDreamSmartspaceController); + mDreamSmartspaceController, mock(Resources.class)); controller.onViewAttached(); verify(mDreamSmartspaceController).addUnfilteredListener(any()); controller.onViewDetached(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java index 51c258055465..23516c94d851 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java @@ -45,6 +45,7 @@ import androidx.slice.core.SliceQuery; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.SystemUIInitializerImpl; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; @@ -100,7 +101,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mIsZenMode = false; mProvider = new TestableKeyguardSliceProvider(); - mProvider.setContextAvailableCallback(context -> { }); + mProvider.setContextAvailableCallback(context -> new SystemUIInitializerImpl(mContext)); mProvider.attachInfo(getContext(), null); reset(mContentResolver); SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST))); diff --git a/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt new file mode 100644 index 000000000000..4f5c570ee812 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt @@ -0,0 +1,150 @@ +package com.android.systemui.lifecycle + +import android.view.View +import android.view.ViewTreeObserver +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleRegistry +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(JUnit4::class) +class WindowAddedViewLifecycleOwnerTest : SysuiTestCase() { + + @Mock lateinit var view: View + @Mock lateinit var viewTreeObserver: ViewTreeObserver + + private lateinit var underTest: WindowAddedViewLifecycleOwner + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + whenever(view.viewTreeObserver).thenReturn(viewTreeObserver) + whenever(view.isAttachedToWindow).thenReturn(false) + whenever(view.windowVisibility).thenReturn(View.INVISIBLE) + whenever(view.hasWindowFocus()).thenReturn(false) + + underTest = WindowAddedViewLifecycleOwner(view) { LifecycleRegistry.createUnsafe(it) } + } + + @Test + fun `detached - invisible - does not have focus -- INITIALIZED`() { + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED) + } + + @Test + fun `detached - invisible - has focus -- INITIALIZED`() { + whenever(view.hasWindowFocus()).thenReturn(true) + val captor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>() + verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(captor)) + captor.value.onWindowFocusChanged(true) + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED) + } + + @Test + fun `detached - visible - does not have focus -- INITIALIZED`() { + whenever(view.windowVisibility).thenReturn(View.VISIBLE) + val captor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>() + verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(captor)) + captor.value.onWindowVisibilityChanged(View.VISIBLE) + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED) + } + + @Test + fun `detached - visible - has focus -- INITIALIZED`() { + whenever(view.hasWindowFocus()).thenReturn(true) + val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>() + verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor)) + focusCaptor.value.onWindowFocusChanged(true) + + whenever(view.windowVisibility).thenReturn(View.VISIBLE) + val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>() + verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor)) + visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE) + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED) + } + + @Test + fun `attached - invisible - does not have focus -- CREATED`() { + whenever(view.isAttachedToWindow).thenReturn(true) + val captor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>() + verify(viewTreeObserver).addOnWindowAttachListener(capture(captor)) + captor.value.onWindowAttached() + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED) + } + + @Test + fun `attached - invisible - has focus -- CREATED`() { + whenever(view.isAttachedToWindow).thenReturn(true) + val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>() + verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor)) + attachCaptor.value.onWindowAttached() + + whenever(view.hasWindowFocus()).thenReturn(true) + val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>() + verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor)) + focusCaptor.value.onWindowFocusChanged(true) + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED) + } + + @Test + fun `attached - visible - does not have focus -- STARTED`() { + whenever(view.isAttachedToWindow).thenReturn(true) + val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>() + verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor)) + attachCaptor.value.onWindowAttached() + + whenever(view.windowVisibility).thenReturn(View.VISIBLE) + val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>() + verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor)) + visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE) + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED) + } + + @Test + fun `attached - visible - has focus -- RESUMED`() { + whenever(view.isAttachedToWindow).thenReturn(true) + val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>() + verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor)) + attachCaptor.value.onWindowAttached() + + whenever(view.hasWindowFocus()).thenReturn(true) + val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>() + verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor)) + focusCaptor.value.onWindowFocusChanged(true) + + whenever(view.windowVisibility).thenReturn(View.VISIBLE) + val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>() + verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor)) + visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE) + + assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED) + } + + @Test + fun dispose() { + underTest.dispose() + + verify(viewTreeObserver).removeOnWindowAttachListener(any()) + verify(viewTreeObserver).removeOnWindowVisibilityChangeListener(any()) + verify(viewTreeObserver).removeOnWindowFocusChangeListener(any()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java index 226182961934..568e0cb22f18 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java @@ -78,7 +78,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices); when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false); - when(mMediaOutputController.isZeroMode()).thenReturn(false); when(mMediaOutputController.isTransferring()).thenReturn(false); when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat); when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat); @@ -98,28 +97,12 @@ public class MediaOutputAdapterTest extends SysuiTestCase { } @Test - public void getItemCount_nonZeroMode_isDeviceSize() { - assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size()); - } - - @Test - public void getItemCount_zeroMode_containExtraOneForPairNew() { - when(mMediaOutputController.isZeroMode()).thenReturn(true); - + public void getItemCount_containExtraOneForPairNew() { assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1); } @Test - public void getItemCount_withDynamicGroup_containExtraOneForGroup() { - when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices); - when(mMediaOutputController.isZeroMode()).thenReturn(false); - - assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size()); - } - - @Test - public void onBindViewHolder_zeroMode_bindPairNew_verifyView() { - when(mMediaOutputController.isZeroMode()).thenReturn(true); + public void onBindViewHolder_bindPairNew_verifyView() { mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2); assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); @@ -133,7 +116,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { @Test public void onBindViewHolder_bindGroup_withSessionName_verifyView() { when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices); - when(mMediaOutputController.isZeroMode()).thenReturn(false); when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME); mMediaOutputAdapter.getItemCount(); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); @@ -148,7 +130,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { @Test public void onBindViewHolder_bindGroup_noSessionName_verifyView() { when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices); - when(mMediaOutputController.isZeroMode()).thenReturn(false); when(mMediaOutputController.getSessionName()).thenReturn(null); mMediaOutputAdapter.getItemCount(); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); @@ -257,7 +238,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { @Test public void onItemClick_clickPairNew_verifyLaunchBluetoothPairing() { - when(mMediaOutputController.isZeroMode()).thenReturn(true); mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2); mViewHolder.mContainerLayout.performClick(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index 9eaa20c2afed..d414660018a8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -43,6 +43,8 @@ import android.widget.TextView; import androidx.core.graphics.drawable.IconCompat; import androidx.test.filters.SmallTest; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; @@ -98,10 +100,17 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { private CharSequence mHeaderSubtitle; private String mStopText; private boolean mIsBroadcasting; + private boolean mIsBroadcastIconVisibility; + @Before public void setUp() { when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); + final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = mock( + CachedBluetoothDeviceManager.class); + when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn( + cachedBluetoothDeviceManager); + when(cachedBluetoothDeviceManager.findDevice(any())).thenReturn(null); when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null); when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE); @@ -153,6 +162,27 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { } @Test + public void refresh_broadcastIconVisibilityOff_broadcastIconLayoutNotVisible() { + mIsBroadcastIconVisibility = false; + + mMediaOutputBaseDialogImpl.refresh(); + final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById( + R.id.broadcast_icon); + + assertThat(view.getVisibility()).isEqualTo(View.GONE); + } + @Test + public void refresh_broadcastIconVisibilityOn_broadcastIconLayoutVisible() { + mIsBroadcastIconVisibility = true; + + mMediaOutputBaseDialogImpl.refresh(); + final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById( + R.id.broadcast_icon); + + assertThat(view.getVisibility()).isEqualTo(View.VISIBLE); + } + + @Test public void refresh_checkTitle() { mHeaderTitle = "test_string"; @@ -308,5 +338,10 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { public CharSequence getStopButtonText() { return mStopText; } + + @Override + public int getBroadcastIconVisibility() { + return mIsBroadcastIconVisibility ? View.VISIBLE : View.GONE; + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index 2bf5f0fcbfcb..751c8951859c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -383,62 +383,6 @@ public class MediaOutputControllerTest extends SysuiTestCase { } @Test - public void isZeroMode_onlyFromPhoneOutput_returnTrue() { - // Multiple available devices - assertThat(mMediaOutputController.isZeroMode()).isFalse(); - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE); - mMediaDevices.clear(); - mMediaDevices.add(mMediaDevice1); - mMediaOutputController.start(mCb); - mMediaOutputController.onDeviceListUpdate(mMediaDevices); - - assertThat(mMediaOutputController.isZeroMode()).isTrue(); - - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE); - - assertThat(mMediaOutputController.isZeroMode()).isTrue(); - - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE); - - assertThat(mMediaOutputController.isZeroMode()).isTrue(); - } - - @Test - public void isZeroMode_notFromPhoneOutput_returnFalse() { - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_UNKNOWN); - mMediaDevices.clear(); - mMediaDevices.add(mMediaDevice1); - mMediaOutputController.start(mCb); - mMediaOutputController.onDeviceListUpdate(mMediaDevices); - - assertThat(mMediaOutputController.isZeroMode()).isFalse(); - - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_FAST_PAIR_BLUETOOTH_DEVICE); - - assertThat(mMediaOutputController.isZeroMode()).isFalse(); - - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE); - - assertThat(mMediaOutputController.isZeroMode()).isFalse(); - - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE); - - assertThat(mMediaOutputController.isZeroMode()).isFalse(); - - when(mMediaDevice1.getDeviceType()).thenReturn( - MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE); - - assertThat(mMediaOutputController.isZeroMode()).isFalse(); - } - - @Test public void getGroupMediaDevices_differentDeviceOrder_showingSameOrder() { final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class); final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index c45db05bacee..6afed1a846b0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -172,6 +172,39 @@ public class MediaOutputDialogTest extends SysuiTestCase { } @Test + public void getBroadcastIconVisibility_isBroadcasting_returnVisible() { + when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn( + mLocalBluetoothLeBroadcast); + when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(true); + when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING); + when(mMediaDevice.isBLEDevice()).thenReturn(true); + + assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.VISIBLE); + } + + @Test + public void getBroadcastIconVisibility_noBroadcasting_returnGone() { + when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn( + mLocalBluetoothLeBroadcast); + when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false); + when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING); + when(mMediaDevice.isBLEDevice()).thenReturn(true); + + assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.GONE); + } + + @Test + public void getBroadcastIconVisibility_remoteNonLeDevice_returnGone() { + when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn( + mLocalBluetoothLeBroadcast); + when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false); + when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING); + when(mMediaDevice.isBLEDevice()).thenReturn(false); + + assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.GONE); + } + + @Test // Check the visibility metric logging by creating a new MediaOutput dialog, // and verify if the calling times increases. public void onCreate_ShouldLogVisibility() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 1cfa3b2a08ff..8fa5c9324416 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -89,6 +89,7 @@ import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserTracker; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shared.rotation.RotationButtonController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; @@ -97,7 +98,6 @@ import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LightBarTransitionsController; -import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt new file mode 100644 index 000000000000..cfbb82f5f338 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.tiles + +import android.os.Handler +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.internal.logging.MetricsLogger +import com.android.internal.logging.UiEventLogger +import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.classifier.FalsingManagerFake +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.qs.QSHost +import com.android.systemui.qs.logging.QSLogger +import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import org.mockito.Mockito.`when` as whenever + +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +@SmallTest +class CameraToggleTileTest : SysuiTestCase() { + companion object { + /* isBlocked */ + const val CAMERA_TOGGLE_ENABLED: Boolean = false + const val CAMERA_TOGGLE_DISABLED: Boolean = true + } + + @Mock + private lateinit var host: QSHost + @Mock + private lateinit var metricsLogger: MetricsLogger + @Mock + private lateinit var statusBarStateController: StatusBarStateController + @Mock + private lateinit var activityStarter: ActivityStarter + @Mock + private lateinit var qsLogger: QSLogger + @Mock + private lateinit var privacyController: IndividualSensorPrivacyController + @Mock + private lateinit var keyguardStateController: KeyguardStateController + + private lateinit var testableLooper: TestableLooper + private lateinit var tile: CameraToggleTile + private val uiEventLogger: UiEventLogger = UiEventLoggerFake() + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + testableLooper = TestableLooper.get(this) + whenever(host.context).thenReturn(mContext) + whenever(host.uiEventLogger).thenReturn(uiEventLogger) + + tile = CameraToggleTile(host, + testableLooper.looper, + Handler(testableLooper.looper), + metricsLogger, + FalsingManagerFake(), + statusBarStateController, + activityStarter, + qsLogger, + privacyController, + keyguardStateController) + } + + @Test + fun testIcon_whenCameraAccessEnabled_isOnState() { + val state = QSTile.BooleanState() + + tile.handleUpdateState(state, CAMERA_TOGGLE_ENABLED) + + assertThat(state.icon) + .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_camera_access_icon_on)) + } + + @Test + fun testIcon_whenCameraAccessDisabled_isOffState() { + val state = QSTile.BooleanState() + + tile.handleUpdateState(state, CAMERA_TOGGLE_DISABLED) + + assertThat(state.icon) + .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_camera_access_icon_off)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java index 7ab49584f0e3..e1eda117177d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java @@ -32,7 +32,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.app.PendingIntent; -import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.testing.AndroidTestingRunner; @@ -115,7 +114,7 @@ public class ActionProxyReceiverTest extends SysuiTestCase { actionProxyReceiver.onReceive(mContext, mIntent); verify(mMockScreenshotSmartActions, never()) - .notifyScreenshotAction(any(Context.class), anyString(), anyString(), anyBoolean(), + .notifyScreenshotAction(anyString(), anyString(), anyBoolean(), any(Intent.class)); } @@ -129,7 +128,7 @@ public class ActionProxyReceiverTest extends SysuiTestCase { actionProxyReceiver.onReceive(mContext, mIntent); verify(mMockScreenshotSmartActions).notifyScreenshotAction( - mContext, testId, ACTION_TYPE_SHARE, false, null); + testId, ACTION_TYPE_SHARE, false, null); } private ActionProxyReceiver constructActionProxyReceiver(boolean withStatusBar) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DeleteScreenshotReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DeleteScreenshotReceiverTest.java index 664c125533d1..d58f47a0469a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DeleteScreenshotReceiverTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DeleteScreenshotReceiverTest.java @@ -31,7 +31,6 @@ import static org.mockito.Mockito.verify; import android.content.ContentResolver; import android.content.ContentValues; -import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; @@ -81,7 +80,7 @@ public class DeleteScreenshotReceiverTest extends SysuiTestCase { verify(mMockExecutor, never()).execute(any(Runnable.class)); verify(mMockScreenshotSmartActions, never()).notifyScreenshotAction( - any(Context.class), any(String.class), any(String.class), anyBoolean(), + any(String.class), any(String.class), anyBoolean(), any(Intent.class)); } @@ -113,7 +112,7 @@ public class DeleteScreenshotReceiverTest extends SysuiTestCase { } // ensure smart actions not called by default - verify(mMockScreenshotSmartActions, never()).notifyScreenshotAction(any(Context.class), + verify(mMockScreenshotSmartActions, never()).notifyScreenshotAction( any(String.class), any(String.class), anyBoolean(), any(Intent.class)); } @@ -129,7 +128,7 @@ public class DeleteScreenshotReceiverTest extends SysuiTestCase { mDeleteScreenshotReceiver.onReceive(mContext, intent); verify(mMockExecutor).execute(any(Runnable.class)); - verify(mMockScreenshotSmartActions).notifyScreenshotAction(mContext, testId, + verify(mMockScreenshotSmartActions).notifyScreenshotAction(testId, ACTION_TYPE_DELETE, false, null); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java index 3d658ec8e811..69b7b88b0524 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java @@ -43,7 +43,6 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; -import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; @@ -71,7 +70,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { public void setup() { mSmartActionsProvider = mock( ScreenshotNotificationSmartActionsProvider.class); - mScreenshotSmartActions = new ScreenshotSmartActions(); + mScreenshotSmartActions = new ScreenshotSmartActions(() -> mSmartActionsProvider); mHandler = mock(Handler.class); } @@ -158,8 +157,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { Bitmap bitmap = mock(Bitmap.class); when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE); ScreenshotNotificationSmartActionsProvider actionsProvider = - SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider( - mContext, null, mHandler); + new ScreenshotNotificationSmartActionsProvider(); CompletableFuture<List<Notification.Action>> smartActionsFuture = mScreenshotSmartActions.getSmartActionsFuture("", null, bitmap, actionsProvider, REGULAR_SMART_ACTIONS, @@ -183,7 +181,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { data.mActionsReadyListener = null; SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, null, mScreenshotSmartActions, data, - ActionTransition::new); + ActionTransition::new, mSmartActionsProvider); Notification.Action shareAction = task.createShareAction(mContext, mContext.getResources(), Uri.parse("Screenshot_123.png")).get().action; @@ -211,7 +209,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { data.mActionsReadyListener = null; SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, null, mScreenshotSmartActions, data, - ActionTransition::new); + ActionTransition::new, mSmartActionsProvider); Notification.Action editAction = task.createEditAction(mContext, mContext.getResources(), Uri.parse("Screenshot_123.png")).get().action; @@ -239,7 +237,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { data.mActionsReadyListener = null; SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, null, mScreenshotSmartActions, data, - ActionTransition::new); + ActionTransition::new, mSmartActionsProvider); Notification.Action deleteAction = task.createDeleteAction(mContext, mContext.getResources(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java index 011e6b7b1071..83c949793447 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java @@ -74,6 +74,6 @@ public class SmartActionsReceiverTest extends SysuiTestCase { verify(mMockPendingIntent).send( eq(mContext), eq(0), isNull(), isNull(), isNull(), isNull(), any(Bundle.class)); verify(mMockScreenshotSmartActions).notifyScreenshotAction( - mContext, testId, testActionType, true, intent); + testId, testActionType, true, intent); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt new file mode 100644 index 000000000000..73226fa0b12c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.settings + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.IntentFilter +import android.os.Environment +import android.os.UserManager +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import java.util.concurrent.Executor +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.isNull +import org.mockito.Mockito.spy +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class UserFileManagerImplTest : SysuiTestCase() { + companion object { + const val TEST_FILE_NAME = "abc.txt" + } + + lateinit var userFileManager: UserFileManagerImpl + lateinit var backgroundExecutor: FakeExecutor + @Mock + lateinit var userManager: UserManager + @Mock + lateinit var broadcastDispatcher: BroadcastDispatcher + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + backgroundExecutor = FakeExecutor(FakeSystemClock()) + userFileManager = UserFileManagerImpl(context, userManager, + broadcastDispatcher, backgroundExecutor) + } + + @Test + fun testGetFile() { + assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path) + .isEqualTo("${context.filesDir}/$TEST_FILE_NAME") + assertThat(userFileManager.getFile(TEST_FILE_NAME, 11).path) + .isEqualTo("${context.filesDir}/${UserFileManagerImpl.ID}/11/files/$TEST_FILE_NAME") + } + + @Test + fun testGetSharedPreferences() { + assertThat(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0)) + .isNotEqualTo(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11)) + } + + @Test + fun testUserFileManagerStart() { + val userFileManager = spy(userFileManager) + userFileManager.start() + verify(userFileManager).clearDeletedUserData() + verify(broadcastDispatcher).registerReceiver(any(BroadcastReceiver::class.java), + any(IntentFilter::class.java), + any(Executor::class.java), isNull(), eq(Context.RECEIVER_EXPORTED), isNull()) + } + + @Test + fun testClearDeletedUserData() { + val dir = Environment.buildPath( + context.filesDir, + UserFileManagerImpl.ID, + "11", + "files" + ) + dir.mkdirs() + val file = Environment.buildPath( + context.filesDir, + UserFileManagerImpl.ID, + "11", + "files", + TEST_FILE_NAME + ) + val secondaryUserDir = Environment.buildPath( + context.filesDir, + UserFileManagerImpl.ID, + "11", + ) + file.createNewFile() + assertThat(secondaryUserDir.exists()).isTrue() + assertThat(file.exists()).isTrue() + userFileManager.clearDeletedUserData() + assertThat(backgroundExecutor.runAllReady()).isGreaterThan(0) + verify(userManager).aliveUsers + assertThat(secondaryUserDir.exists()).isFalse() + assertThat(file.exists()).isFalse() + dir.deleteRecursively() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index d55875994468..5abcff3c56f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; @@ -106,6 +106,7 @@ import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; import com.android.systemui.screenrecord.RecordingController; +import com.android.systemui.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; @@ -131,8 +132,28 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator; +import com.android.systemui.statusbar.phone.CentralSurfaces; +import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; +import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; +import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; +import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; +import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.KeyguardStatusBarView; +import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController; +import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController; +import com.android.systemui.statusbar.phone.LockscreenGestureLogger; +import com.android.systemui.statusbar.phone.NotificationIconAreaController; +import com.android.systemui.statusbar.phone.PanelViewController; +import com.android.systemui.statusbar.phone.ScreenOffAnimationController; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.phone.TapAgainViewController; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; -import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -173,6 +194,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Mock private KeyguardBottomAreaView mKeyguardBottomArea; @Mock + private KeyguardBottomAreaViewController mKeyguardBottomAreaViewController; + @Mock private KeyguardBottomAreaView mQsFrame; private KeyguardStatusView mKeyguardStatusView; @Mock @@ -400,6 +423,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000); when(mNotificationStackScrollLayoutController.getHeadsUpCallback()) .thenReturn(mHeadsUpCallback); + when(mKeyguardBottomAreaViewController.getView()).thenReturn(mKeyguardBottomArea); when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea); when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class)); when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame); @@ -482,7 +506,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mMainHandler = new Handler(Looper.getMainLooper()); mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter(); - mNotificationPanelViewController = new NotificationPanelViewController(mView, + mNotificationPanelViewController = new NotificationPanelViewController( + mView, mMainHandler, mLayoutInflater, mFeatureFlags, @@ -533,6 +558,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mInteractionJankMonitor, mQsFrameTranslateController, mSysUiState, + () -> mKeyguardBottomAreaViewController, mKeyguardUnlockAnimationController, mNotificationListContainer, mPanelEventsEmitter, @@ -558,7 +584,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { ArgumentCaptor.forClass(View.AccessibilityDelegate.class); verify(mView).setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture()); mAccessibiltyDelegate = accessibilityDelegateArgumentCaptor.getValue(); - mNotificationPanelViewController.mStatusBarStateController + mNotificationPanelViewController.getStatusBarStateController() .addCallback(mNotificationPanelViewController.mStatusBarStateListener); mNotificationPanelViewController .setHeadsUpAppearanceController(mock(HeadsUpAppearanceController.class)); @@ -986,6 +1012,21 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } @Test + public void testSwipe_exactlyToTarget_notifiesNssl() { + // No over-expansion + mNotificationPanelViewController.setOverExpansion(0f); + // Fling to a target that is equal to the current position (i.e. a no-op fling). + mNotificationPanelViewController.flingToHeight( + 0f, + true, + mNotificationPanelViewController.getExpandedHeight(), + 1f, + false); + // Verify that the NSSL is notified that the panel is *not* flinging. + verify(mNotificationStackScrollLayoutController).setPanelFlinging(false); + } + + @Test public void testDoubleTapRequired_Keyguard() { FalsingManager.FalsingTapListener listener = getFalsingTapListener(); mStatusBarStateController.setState(KEYGUARD); @@ -1172,14 +1213,14 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { when(mPowerManager.isPowerSaveMode()).thenReturn(false); when(mAmbientState.getDozeAmount()).thenReturn(0f); mNotificationPanelViewController.startUnlockHintAnimation(); - assertThat(mNotificationPanelViewController.mHintAnimationRunning).isTrue(); + assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isTrue(); } @Test public void testUnlockHintAnimation_doesNotRun_inPowerSaveMode() { when(mPowerManager.isPowerSaveMode()).thenReturn(true); mNotificationPanelViewController.startUnlockHintAnimation(); - assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse(); + assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse(); } @Test @@ -1187,7 +1228,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { when(mPowerManager.isPowerSaveMode()).thenReturn(false); when(mAmbientState.getDozeAmount()).thenReturn(0.5f); mNotificationPanelViewController.startUnlockHintAnimation(); - assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse(); + assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse(); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt index de40b7fd0a13..0c6a6a98052f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone +package com.android.systemui.shade import android.testing.AndroidTestingRunner import android.testing.TestableLooper diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java index c402d2e47cf3..1dfd7c26ecbb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; @@ -28,8 +28,10 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -42,6 +44,8 @@ import android.testing.TestableLooper.RunWithLooper; import android.view.View; import android.view.WindowManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewTreeLifecycleOwner; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; @@ -51,6 +55,11 @@ import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl; +import com.android.systemui.statusbar.phone.ScreenOffAnimationController; +import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -61,6 +70,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.Spy; @RunWith(AndroidTestingRunner.class) @RunWithLooper @@ -69,7 +79,8 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { @Mock private WindowManager mWindowManager; @Mock private DozeParameters mDozeParameters; - @Mock private NotificationShadeWindowView mNotificationShadeWindowView; + @Spy private final NotificationShadeWindowView mNotificationShadeWindowView = spy( + new NotificationShadeWindowView(mContext, null)); @Mock private IActivityManager mActivityManager; @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock private ConfigurationController mConfigurationController; @@ -85,6 +96,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; + @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -177,6 +189,24 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { } @Test + public void attach_setsUpLifecycleOwner() { + mNotificationShadeWindowController.attach(); + + assertThat(ViewTreeLifecycleOwner.get(mNotificationShadeWindowView)).isNotNull(); + } + + @Test + public void attach_doesNotSetUpLifecycleOwnerIfAlreadySet() { + final LifecycleOwner previouslySet = mock(LifecycleOwner.class); + ViewTreeLifecycleOwner.set(mNotificationShadeWindowView, previouslySet); + + mNotificationShadeWindowController.attach(); + + assertThat(ViewTreeLifecycleOwner.get(mNotificationShadeWindowView)) + .isEqualTo(previouslySet); + } + + @Test public void setScrimsVisibility_earlyReturn() { clearInvocations(mWindowManager); mNotificationShadeWindowController.setScrimsVisibility(ScrimController.TRANSPARENT); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index 7982bc0c101c..471918cfa695 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone +package com.android.systemui.shade import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper @@ -32,7 +32,10 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController -import com.android.systemui.statusbar.phone.NotificationShadeWindowView.InteractionEventHandler +import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler +import com.android.systemui.statusbar.phone.CentralSurfaces +import com.android.systemui.statusbar.phone.PhoneStatusBarViewController +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager import com.android.systemui.statusbar.window.StatusBarWindowStateController import com.android.systemui.tuner.TunerService diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java index 1d86fb13a1f6..665d849e379e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.phone; +package com.android.systemui.shade; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -47,6 +47,9 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.phone.CentralSurfaces; +import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.window.StatusBarWindowStateController; import com.android.systemui.tuner.TunerService; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt index 304a274576b7..baaa447d53a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt index 8b7e04bbab1b..d6faaee51087 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest @@ -6,8 +6,8 @@ import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS +import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController -import com.android.systemui.statusbar.phone.NotificationPanelViewController import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt index 5ca15bb93d31..aafd871f72f3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt @@ -1,4 +1,4 @@ -package com.android.systemui.statusbar.phone.shade.transition +package com.android.systemui.shade.transition import android.testing.AndroidTestingRunner import android.testing.TestableLooper diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index d67e26f138f2..9c25462b7c0d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -30,6 +30,7 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED; +import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON; import static com.google.common.truth.Truth.assertThat; @@ -212,7 +213,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME); when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true); - when(mScreenLifecycle.getScreenState()).thenReturn(ScreenLifecycle.SCREEN_ON); + when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON); when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true); when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom)) @@ -954,64 +955,170 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { } @Test - public void nonBypassFaceSuccess_touchExplorationEnabled_showsSwipeToOpen() { - // GIVEN non bypass face auth and touch exploration is enabled - when(mKeyguardBypassController.canBypass()).thenReturn(false); - when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); + public void coEx_faceSuccess_showsPressToOpen() { + // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, no a11y enabled when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(true); + when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); + when(mAccessibilityManager.isEnabled()).thenReturn(false); + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); + createController(); + mController.setVisible(true); + + // WHEN face auth succeeds + when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); + mController.getKeyguardCallback().onBiometricAuthenticated(0, + BiometricSourceType.FACE, false); + + // THEN 'face unlocked. press unlock icon to open' message shows + String pressToOpen = mContext.getString(R.string.keyguard_face_successful_unlock_press); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen); + + assertThat(mTextView.getText()).isNotEqualTo(pressToOpen); + } + + + @Test + public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() { + // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(true); + when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); + when(mAccessibilityManager.isEnabled()).thenReturn(true); + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); createController(); - String swipeToOpen = mContext.getString(R.string.keyguard_unlock); mController.setVisible(true); // WHEN face authenticated + when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); mController.getKeyguardCallback().onBiometricAuthenticated(0, BiometricSourceType.FACE, false); - // THEN show 'swipe up to open' message - verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); + // THEN show 'face unlocked. swipe up to open' message + String faceUnlockedSwipeToOpen = + mContext.getString(R.string.keyguard_face_successful_unlock_swipe); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen); } @Test - public void nonBypassFaceSuccess_a11yEnabled_showsSwipeToOpen() { - // GIVEN non bypass face auth and a11y is enabled - when(mKeyguardBypassController.canBypass()).thenReturn(false); + public void coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen() { + // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(true); + when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); when(mAccessibilityManager.isEnabled()).thenReturn(true); + createController(); + mController.setVisible(true); + + // WHEN face auth is successful + when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); + mController.getKeyguardCallback().onBiometricAuthenticated(0, + BiometricSourceType.FACE, false); + + // THEN show 'swipe up to open' message + String faceUnlockedSwipeToOpen = + mContext.getString(R.string.keyguard_face_successful_unlock_swipe); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen); + } + + @Test + public void faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen() { + // GIVEN bouncer isn't showing, can skip bouncer, no udfps supported when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(true); + when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); createController(); - String swipeToOpen = mContext.getString(R.string.keyguard_unlock); mController.setVisible(true); // WHEN face auth is successful + when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); mController.getKeyguardCallback().onBiometricAuthenticated(0, BiometricSourceType.FACE, false); // THEN show 'swipe up to open' message + String faceUnlockedSwipeToOpen = + mContext.getString(R.string.keyguard_face_successful_unlock_swipe); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen); + } + + @Test + public void udfpsOnly_a11yEnabled_showsSwipeToOpen() { + // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(true); + when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); + when(mAccessibilityManager.isEnabled()).thenReturn(true); + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); + createController(); + mController.setVisible(true); + + // WHEN showActionToUnlock + mController.showActionToUnlock(); + + // THEN show 'swipe up to open' message + String swipeToOpen = mContext.getString(R.string.keyguard_unlock); verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); } @Test - public void coEx_nonBypassFaceSuccess_showsPressLockIcon() { - // GIVEN udfps is supported, non-bypass face auth, and no a11y enabled + public void udfpsOnly_showsPressToOpen() { + // GIVEN bouncer isn't showing, udfps is supported, a11y is NOT enabled, can skip bouncer + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(true); when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); - when(mKeyguardBypassController.canBypass()).thenReturn(false); - when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); when(mAccessibilityManager.isEnabled()).thenReturn(false); when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); + createController(); + mController.setVisible(true); + + // WHEN showActionToUnlock + mController.showActionToUnlock(); + + // THEN show 'press unlock icon to open' message + String pressToOpen = mContext.getString(R.string.keyguard_unlock_press); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen); + } + + @Test + public void canSkipBouncer_noSecurity_showSwipeToUnlockHint() { + // GIVEN bouncer isn't showing, can skip bouncer, no security (udfps isn't supported, + // face wasn't authenticated) when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) .thenReturn(true); + when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); createController(); mController.setVisible(true); - // WHEN face auth succeeds - mController.getKeyguardCallback().onBiometricAuthenticated(0, - BiometricSourceType.FACE, false); + // WHEN showActionToUnlock + mController.showActionToUnlock(); - // THEN press unlock icon to open message shows - String pressLockIcon = mContext.getString(R.string.keyguard_face_successful_unlock_press); - verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressLockIcon); + // THEN show 'swipe up to open' message + String swipeToOpen = mContext.getString(R.string.keyguard_unlock); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); + } - assertThat(mTextView.getText()).isNotEqualTo(pressLockIcon); + @Test + public void cannotSkipBouncer_showSwipeToUnlockHint() { + // GIVEN bouncer isn't showing and cannot skip bouncer + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser())) + .thenReturn(false); + createController(); + mController.setVisible(true); + + // WHEN showActionToUnlock + mController.showActionToUnlock(); + + // THEN show 'swipe up to open' message + String swipeToOpen = mContext.getString(R.string.keyguard_unlock); + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); } private void sendUpdateDisclosureBroadcast() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 562c97017862..fe1cd978ef91 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -1,6 +1,5 @@ package com.android.systemui.statusbar -import org.mockito.Mockito.`when` as whenever import android.test.suitebuilder.annotation.SmallTest import android.testing.AndroidTestingRunner import android.testing.TestableLooper @@ -14,6 +13,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.media.MediaHierarchyManager import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QS +import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.AmbientState @@ -22,7 +22,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.LSShadeTransitionLogger -import com.android.systemui.statusbar.phone.NotificationPanelViewController import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.policy.FakeConfigurationController import org.junit.After @@ -45,6 +44,7 @@ import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions +import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit private fun <T> anyObject(): T { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt index 9f82a5673c6e..f4458bbdc497 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt @@ -6,11 +6,11 @@ import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase +import com.android.systemui.shade.NotificationShadeWindowViewController import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.phone.HeadsUpManagerPhone -import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController import com.android.systemui.statusbar.policy.HeadsUpUtil import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue @@ -19,8 +19,8 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnit @SmallTest diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java index 96c40ecd3d81..c961cec39208 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java @@ -36,6 +36,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotifPanelEvents; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -44,7 +45,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable; import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; -import com.android.systemui.statusbar.phone.NotifPanelEvents; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java index 4efd5c995a97..c199147b4f79 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java @@ -52,6 +52,7 @@ import com.android.systemui.media.KeyguardMediaController; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener; @@ -75,7 +76,6 @@ import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ShadeController; -import com.android.systemui.statusbar.phone.shade.transition.ShadeTransitionController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.ZenModeController; @@ -150,7 +150,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper); - when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false); mController = new NotificationStackScrollLayoutController( true, @@ -166,7 +165,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mKeyguardMediaController, mKeyguardBypassController, mZenModeController, - mColorExtractor, mNotificationLockscreenUserManager, mMetricsLogger, mDumpManager, @@ -179,15 +177,12 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mLegacyGroupManager, mLegacyGroupManager, mSilentHeaderController, - mNotifPipelineFlags, mNotifPipeline, mNotifCollection, mEntryManager, mLockscreenShadeTransitionController, mShadeTransitionController, - mIStatusBarService, mUiEventLogger, - mLayoutInflater, mRemoteInputManager, mVisualStabilityManager, mShadeController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java index 9bfb2c4ce00c..d79f3361408b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java @@ -37,6 +37,8 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; import com.android.systemui.statusbar.StatusBarStateControllerImpl; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 74fb7f67940d..b75c52ad283e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -105,6 +105,10 @@ import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.settings.brightness.BrightnessSliderController; +import com.android.systemui.shade.NotificationPanelView; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java index 26ac70c70e7f..5c9871a01536 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java @@ -41,6 +41,8 @@ import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java index ed22cd3c55fc..103b7b4268de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java @@ -34,6 +34,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index 39021d8732d3..60a3d95e24f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -230,6 +230,15 @@ public class KeyguardBouncerTest extends SysuiTestCase { } @Test + public void show_notifiesKeyguardViewController() { + mBouncer.ensureView(); + + mBouncer.show(/* resetSecuritySelection= */ false); + + verify(mKeyguardHostViewController).onBouncerVisibilityChanged(View.VISIBLE); + } + + @Test public void testHide_notifiesFalsingManager() { mBouncer.hide(false); verify(mFalsingCollector).onBouncerHidden(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java index 4e1a7088b17f..11e502fc79bf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java @@ -49,6 +49,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.battery.BatteryMeterViewController; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserInfoTracker; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 0c1d04253bf5..79fce82a1bcd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -47,6 +47,7 @@ import com.android.systemui.dock.DockManager; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -275,21 +276,18 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { // Should be false to start, so no invocations mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, false /* animated */); - verify(mKeyguardUpdateMonitor, never()).onKeyguardOccludedChanged(anyBoolean()); verify(mKeyguardStateController, never()).notifyKeyguardState(anyBoolean(), anyBoolean()); clearInvocations(mKeyguardUpdateMonitor); clearInvocations(mKeyguardStateController); mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */); - verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true); verify(mKeyguardStateController).notifyKeyguardState(true, true); clearInvocations(mKeyguardUpdateMonitor); clearInvocations(mKeyguardStateController); mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */); - verify(mKeyguardUpdateMonitor, never()).onKeyguardOccludedChanged(anyBoolean()); verify(mKeyguardStateController, never()).notifyKeyguardState(anyBoolean(), anyBoolean()); } @@ -299,7 +297,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mStatusBarKeyguardViewManager.show(null); mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */); - verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true); verify(mKeyguardStateController).notifyKeyguardState(true, true); } @@ -309,7 +306,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mStatusBarKeyguardViewManager.show(null); mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */); - verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true); verify(mKeyguardStateController).notifyKeyguardState(true, true); } @@ -389,6 +385,16 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { } @Test + public void testBouncerIsOrWillBeShowing_whenBouncerIsInTransit() { + when(mBouncer.isShowing()).thenReturn(false); + when(mBouncer.inTransit()).thenReturn(true); + + assertTrue( + "Is or will be showing should be true when bouncer is in transit", + mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()); + } + + @Test public void testShowAltAuth_unlockingWithBiometricNotAllowed() { // GIVEN alt auth exists, unlocking with biometric isn't allowed mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index ecea14c6a522..7046150ba373 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -59,18 +59,17 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.statusbar.NotificationClickNotifier; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -127,8 +126,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { @Mock private ShadeControllerImpl mShadeController; @Mock - private NotifPipelineFlags mNotifPipelineFlags; - @Mock private NotifPipeline mNotifPipeline; @Mock private NotificationVisibilityProvider mVisibilityProvider; @@ -148,15 +145,13 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { private ActivityLaunchAnimator mActivityLaunchAnimator; @Mock private InteractionJankMonitor mJankMonitor; - private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); - private NotificationTestHelper mNotificationTestHelper; + private final FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); private ExpandableNotificationRow mNotificationRow; private ExpandableNotificationRow mBubbleNotificationRow; private final Answer<Void> mCallOnDismiss = answerVoid( (OnDismissAction dismissAction, Runnable cancel, Boolean afterKeyguardGone) -> dismissAction.onDismiss()); - private ArrayList<NotificationEntry> mActiveNotifications; @Before public void setUp() throws Exception { @@ -165,29 +160,28 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1)); when(mContentIntent.getIntent()).thenReturn(mContentIntentInner); - mNotificationTestHelper = new NotificationTestHelper( + NotificationTestHelper notificationTestHelper = new NotificationTestHelper( mContext, mDependency, TestableLooper.get(this)); // Create standard notification with contentIntent - mNotificationRow = mNotificationTestHelper.createRow(); + mNotificationRow = notificationTestHelper.createRow(); StatusBarNotification sbn = mNotificationRow.getEntry().getSbn(); sbn.getNotification().contentIntent = mContentIntent; sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; // Create bubble notification row with contentIntent - mBubbleNotificationRow = mNotificationTestHelper.createBubble(); + mBubbleNotificationRow = notificationTestHelper.createBubble(); StatusBarNotification bubbleSbn = mBubbleNotificationRow.getEntry().getSbn(); bubbleSbn.getNotification().contentIntent = mContentIntent; bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; - mActiveNotifications = new ArrayList<>(); - mActiveNotifications.add(mNotificationRow.getEntry()); - mActiveNotifications.add(mBubbleNotificationRow.getEntry()); - when(mEntryManager.getVisibleNotifications()).thenReturn(mActiveNotifications); + ArrayList<NotificationEntry> activeNotifications = new ArrayList<>(); + activeNotifications.add(mNotificationRow.getEntry()); + activeNotifications.add(mBubbleNotificationRow.getEntry()); + when(mEntryManager.getVisibleNotifications()).thenReturn(activeNotifications); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); - when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false); when(mOnUserInteractionCallback.registerFutureDismissal(eq(mNotificationRow.getEntry()), anyInt())).thenReturn(mFutureDismissalRunnable); when(mVisibilityProvider.obtain(anyString(), anyBoolean())) @@ -207,23 +201,19 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mNotificationActivityStarter = new StatusBarNotificationActivityStarter( getContext(), - mock(CommandQueue.class), mHandler, mUiBgExecutor, - mEntryManager, mNotifPipeline, mVisibilityProvider, headsUpManager, mActivityStarter, mClickNotifier, - mock(StatusBarStateController.class), mStatusBarKeyguardViewManager, mock(KeyguardManager.class), mock(IDreamManager.class), Optional.of(mBubblesManager), () -> mAssistManager, mRemoteInputManager, - mock(NotificationGroupManagerLegacy.class), mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardStateController, @@ -231,7 +221,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mock(LockPatternUtils.class), mock(StatusBarRemoteInputCallback.class), mActivityIntentHelper, - mNotifPipelineFlags, mock(MetricsLogger.class), mock(StatusBarNotificationActivityStarterLogger.class), mOnUserInteractionCallback, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 1a3dd3a7a2a5..4b5d1f747ca0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -33,12 +33,13 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.testing.FakeMetricsLogger; -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.ForegroundServiceNotificationListener; import com.android.systemui.InitController; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; @@ -50,7 +51,6 @@ import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; @@ -61,7 +61,6 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; -import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.Before; @@ -125,15 +124,12 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mock(NotificationLockscreenUserManager.class), mock(SysuiStatusBarStateController.class), mock(NotifShadeEventSource.class), - mock(NotificationEntryManager.class), mock(NotificationMediaManager.class), mock(NotificationGutsManager.class), - mock(KeyguardUpdateMonitor.class), lockscreenGestureLogger, mInitController, mNotificationInterruptStateProvider, mock(NotificationRemoteInputManager.class), - mock(ConfigurationController.class), mock(NotifPipelineFlags.class), mock(NotificationRemoteInputManager.Callback.class), mock(NotificationListContainer.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt index 011279721fd2..746c92e485b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt @@ -27,6 +27,7 @@ import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.WakefulnessLifecycle +import com.android.systemui.shade.NotificationPanelViewController import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.StatusBarStateControllerImpl import com.android.systemui.statusbar.policy.KeyguardStateController @@ -39,12 +40,12 @@ import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito -import org.mockito.Mockito.`when` import org.mockito.Mockito.anyLong import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest @@ -184,4 +185,4 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { controller.startAnimation() assertFalse(controller.isAnimationPlaying()) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java index 6abc687f0ebb..3f14494322e3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java @@ -44,7 +44,9 @@ import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.LogcatEchoTracker; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.DisableFlagsLogger; import com.android.systemui.statusbar.OperatorNameViewController; @@ -52,7 +54,6 @@ import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; import com.android.systemui.statusbar.phone.NotificationIconAreaController; -import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; @@ -114,6 +115,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { @Before public void setup() { injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); + mDependency.injectMockDependency(DarkIconDispatcher.class); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt index 1af8a77b1610..09d7c03c2091 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt @@ -54,7 +54,7 @@ import com.android.systemui.plugins.FalsingManager import com.android.systemui.qs.QSUserSwitcherEvent import com.android.systemui.qs.user.UserSwitchDialogController import com.android.systemui.settings.UserTracker -import com.android.systemui.statusbar.phone.NotificationShadeWindowView +import com.android.systemui.shade.NotificationShadeWindowView import com.android.systemui.telephony.TelephonyListenerManager import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt index eaad69c6b9d2..66367ecfc95c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt @@ -23,6 +23,7 @@ import android.view.LayoutInflater import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.plugins.FalsingManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.UserSwitcherController @@ -46,6 +47,8 @@ class UserSwitcherActivityTest : SysuiTestCase() { @Mock private lateinit var layoutInflater: LayoutInflater @Mock + private lateinit var falsingCollector: FalsingCollector + @Mock private lateinit var falsingManager: FalsingManager @Mock private lateinit var userManager: UserManager @@ -59,6 +62,7 @@ class UserSwitcherActivityTest : SysuiTestCase() { userSwitcherController, broadcastDispatcher, layoutInflater, + falsingCollector, falsingManager, userManager, userTracker diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 2e58fc4f93fa..6a0124a3be8a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -71,6 +71,7 @@ import android.testing.TestableLooper; import android.util.Pair; import android.util.SparseArray; import android.view.View; +import android.view.ViewTreeObserver; import android.view.WindowManager; import androidx.test.filters.SmallTest; @@ -84,6 +85,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.RankingBuilder; @@ -104,7 +106,6 @@ import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl; -import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.BatteryController; @@ -132,6 +133,7 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHandedController; +import com.android.wm.shell.sysui.ShellController; import org.junit.Before; import org.junit.Ignore; @@ -213,6 +215,8 @@ public class BubblesTest extends SysuiTestCase { private BubbleEntry mBubbleEntry2User11; @Mock + private ShellController mShellController; + @Mock private Bubbles.BubbleExpandListener mBubbleExpandListener; @Mock private PendingIntent mDeleteIntent; @@ -265,6 +269,8 @@ public class BubblesTest extends SysuiTestCase { ShellExecutor syncExecutor = new SyncExecutor(); when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); + when(mNotificationShadeWindowView.getViewTreeObserver()) + .thenReturn(mock(ViewTreeObserver.class)); mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, @@ -325,6 +331,7 @@ public class BubblesTest extends SysuiTestCase { when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor); mBubbleController = new TestableBubbleController( mContext, + mShellController, mBubbleData, mFloatingContentCoordinator, mDataRepository, @@ -353,7 +360,6 @@ public class BubblesTest extends SysuiTestCase { mNotificationShadeWindowController, mock(KeyguardStateController.class), mShadeController, - mConfigurationController, mStatusBarService, mock(INotificationManager.class), mVisibilityProvider, @@ -375,6 +381,11 @@ public class BubblesTest extends SysuiTestCase { } @Test + public void instantiateController_registerConfigChangeListener() { + verify(mShellController, times(1)).addConfigurationChangeListener(any()); + } + + @Test public void testAddBubble() { mBubbleController.updateBubble(mBubbleEntry); assertTrue(mBubbleController.hasBubbles()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java index 17e5778f7aab..f901c327b76e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java @@ -38,6 +38,7 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHandedController; +import com.android.wm.shell.sysui.ShellController; import java.util.Optional; @@ -48,6 +49,7 @@ public class TestableBubbleController extends BubbleController { // Let's assume surfaces can be synchronized immediately. TestableBubbleController(Context context, + ShellController shellController, BubbleData data, FloatingContentCoordinator floatingContentCoordinator, BubbleDataRepository dataRepository, @@ -67,11 +69,12 @@ public class TestableBubbleController extends BubbleController { Handler shellMainHandler, TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue) { - super(context, data, Runnable::run, floatingContentCoordinator, dataRepository, - statusBarService, windowManager, windowManagerShellWrapper, userManager, - launcherApps, bubbleLogger, taskStackListener, shellTaskOrganizer, positioner, - displayController, oneHandedOptional, dragAndDropController, shellMainExecutor, - shellMainHandler, new SyncExecutor(), taskViewTransitions, syncQueue); + super(context, shellController, data, Runnable::run, floatingContentCoordinator, + dataRepository, statusBarService, windowManager, windowManagerShellWrapper, + userManager, launcherApps, bubbleLogger, taskStackListener, shellTaskOrganizer, + positioner, displayController, oneHandedOptional, dragAndDropController, + shellMainExecutor, shellMainHandler, new SyncExecutor(), taskViewTransitions, + syncQueue); setInflateSynchronously(true); initialize(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index 185942e6fbc8..2b37b9e5366e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -45,6 +45,7 @@ import com.android.wm.shell.onehanded.OneHandedEventCallback; import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.splitscreen.SplitScreen; +import com.android.wm.shell.sysui.ShellInterface; import org.junit.Before; import org.junit.Test; @@ -65,6 +66,7 @@ import java.util.Optional; public class WMShellTest extends SysuiTestCase { WMShell mWMShell; + @Mock ShellInterface mShellInterface; @Mock CommandQueue mCommandQueue; @Mock ConfigurationController mConfigurationController; @Mock KeyguardStateController mKeyguardStateController; @@ -88,12 +90,12 @@ public class WMShellTest extends SysuiTestCase { public void setUp() { MockitoAnnotations.initMocks(this); - mWMShell = new WMShell(mContext, Optional.of(mPip), + mWMShell = new WMShell(mContext, mShellInterface, Optional.of(mPip), Optional.of(mSplitScreen), Optional.of(mOneHanded), Optional.of(mHideDisplayCutout), Optional.of(mShellCommandHandler), Optional.of(mCompatUI), Optional.of(mDragAndDrop), mCommandQueue, mConfigurationController, mKeyguardStateController, - mKeyguardUpdateMonitor, mNavigationModeController, mScreenLifecycle, mSysUiState, + mKeyguardUpdateMonitor, mScreenLifecycle, mSysUiState, mProtoTracer, mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor); } @@ -123,14 +125,6 @@ public class WMShellTest extends SysuiTestCase { } @Test - public void initHideDisplayCutout_registersCallbacks() { - mWMShell.initHideDisplayCutout(mHideDisplayCutout); - - verify(mConfigurationController).addCallback( - any(ConfigurationController.ConfigurationListener.class)); - } - - @Test public void initCompatUI_registersCallbacks() { mWMShell.initCompatUi(mCompatUI); diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 8fe57e18ea37..4892718d6203 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -123,6 +123,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.widget.IRemoteViewsFactory; import com.android.server.LocalServices; +import com.android.server.ServiceThread; import com.android.server.WidgetBackupProvider; import org.xmlpull.v1.XmlPullParser; @@ -266,7 +267,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mSaveStateHandler = BackgroundThread.getHandler(); - mCallbackHandler = new CallbackHandler(mContext.getMainLooper()); + final ServiceThread serviceThread = new ServiceThread(TAG, + android.os.Process.THREAD_PRIORITY_FOREGROUND, false /* allowIo */); + serviceThread.start(); + mCallbackHandler = new CallbackHandler(serviceThread.getLooper()); mBackupRestoreController = new BackupRestoreController(); mSecurityPolicy = new SecurityPolicy(); mIsProviderInfoPersisted = !ActivityManager.isLowRamDeviceStatic() @@ -307,26 +311,26 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); packageFilter.addDataScheme("package"); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - packageFilter, null, null); + packageFilter, null, mCallbackHandler); // Register for events related to sdcard installation. IntentFilter sdFilter = new IntentFilter(); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - sdFilter, null, null); + sdFilter, null, mCallbackHandler); IntentFilter offModeFilter = new IntentFilter(); offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - offModeFilter, null, null); + offModeFilter, null, mCallbackHandler); IntentFilter suspendPackageFilter = new IntentFilter(); suspendPackageFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); suspendPackageFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - suspendPackageFilter, null, null); + suspendPackageFilter, null, mCallbackHandler); } private void registerOnCrossProfileProvidersChangedListener() { @@ -1218,11 +1222,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku try { // Ask ActivityManager to bind it. Notice that we are binding the service with the // caller app instead of DevicePolicyManagerService. - if(ActivityManager.getService().bindService( + if (ActivityManager.getService().bindService( caller, activtiyToken, intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - connection, flags, mContext.getOpPackageName(), - widget.provider.getUserId()) != 0) { + connection, flags & (Context.BIND_AUTO_CREATE + | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE), + mContext.getOpPackageName(), widget.provider.getUserId()) != 0) { // Add it to the mapping of RemoteViewsService to appWidgetIds so that we // can determine when we can call back to the RemoteViewsService later to diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java index a2b20593a9cb..f523773033d1 100644 --- a/services/companion/java/com/android/server/companion/PackageUtils.java +++ b/services/companion/java/com/android/server/companion/PackageUtils.java @@ -30,6 +30,7 @@ import android.companion.CompanionDeviceService; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.FeatureInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.PackageInfoFlags; @@ -39,8 +40,6 @@ import android.content.pm.ServiceInfo; import android.os.Binder; import android.util.Slog; -import com.android.internal.util.ArrayUtils; - import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -65,15 +64,20 @@ final class PackageUtils { static void enforceUsesCompanionDeviceFeature(@NonNull Context context, @UserIdInt int userId, @NonNull String packageName) { - final boolean requested = ArrayUtils.contains( - getPackageInfo(context, userId, packageName).reqFeatures, - FEATURE_COMPANION_DEVICE_SETUP); - - if (requested) { - throw new IllegalStateException("Must declare uses-feature " - + FEATURE_COMPANION_DEVICE_SETUP - + " in manifest to use this API"); + String requiredFeature = FEATURE_COMPANION_DEVICE_SETUP; + + FeatureInfo[] requestedFeatures = getPackageInfo(context, userId, packageName).reqFeatures; + if (requestedFeatures != null) { + for (int i = 0; i < requestedFeatures.length; i++) { + if (requiredFeature.equals(requestedFeatures[i].name)) { + return; + } + } } + + throw new IllegalStateException("Must declare uses-feature " + + requiredFeature + + " in manifest to use this API"); } /** diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index c678a67e5bd3..e1a0bfd25c9f 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -160,6 +160,7 @@ public class Watchdog implements Dumpable { public static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] { "android.hardware.biometrics.face.IFace/", "android.hardware.biometrics.fingerprint.IFingerprint/", + "android.hardware.input.processor.IInputProcessor/", "android.hardware.light.ILights/", "android.hardware.power.IPower/", "android.hardware.power.stats.IPowerStats/", diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 92a8dcd2ba8f..98e3a214435a 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2269,7 +2269,9 @@ public final class ProcessList { final boolean inBgRestricted = ast.isAppBackgroundRestricted( app.info.uid, app.info.packageName); if (inBgRestricted) { - mAppsInBackgroundRestricted.add(app); + synchronized (mService) { + mAppsInBackgroundRestricted.add(app); + } } app.mState.setBackgroundRestricted(inBgRestricted); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 5787efb7933e..9486a45e989e 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1794,6 +1794,7 @@ public class NotificationManagerService extends SystemService { if (userHandle >= 0) { cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, true, userHandle, REASON_PROFILE_TURNED_OFF, null); + mSnoozeHelper.clearData(userHandle); } } else if (action.equals(Intent.ACTION_USER_PRESENT)) { // turn off LED when user passes through lock screen diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java index 1b669322e553..12324bff0c7a 100644 --- a/services/core/java/com/android/server/notification/PermissionHelper.java +++ b/services/core/java/com/android/server/notification/PermissionHelper.java @@ -17,6 +17,7 @@ package com.android.server.notification; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; +import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -176,9 +177,8 @@ public final class PermissionHelper { mPermManager.revokeRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId, TAG); } - int flagMask = userSet || !grant - ? FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT : - FLAG_PERMISSION_USER_SET; + int flagMask = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED; + flagMask = userSet || !grant ? flagMask | FLAG_PERMISSION_GRANTED_BY_DEFAULT : flagMask; if (userSet) { mPermManager.updatePermissionFlags(packageName, NOTIFICATION_PERMISSION, flagMask, FLAG_PERMISSION_USER_SET, true, userId); diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java index 15d7c1e7a210..61936df4a124 100644 --- a/services/core/java/com/android/server/notification/SnoozeHelper.java +++ b/services/core/java/com/android/server/notification/SnoozeHelper.java @@ -16,7 +16,6 @@ package com.android.server.notification; import android.annotation.NonNull; -import android.annotation.UserIdInt; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -25,7 +24,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Binder; -import android.os.SystemClock; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; @@ -38,18 +36,15 @@ import android.util.TypedXmlSerializer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.internal.util.XmlUtils; import com.android.server.pm.PackageManagerService; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -59,7 +54,7 @@ import java.util.Set; /** * NotificationManagerService helper for handling snoozed notifications. */ -public class SnoozeHelper { +public final class SnoozeHelper { public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1; static final int CONCURRENT_SNOOZE_LIMIT = 500; @@ -68,8 +63,6 @@ public class SnoozeHelper { private static final String XML_SNOOZED_NOTIFICATION = "notification"; private static final String XML_SNOOZED_NOTIFICATION_CONTEXT = "context"; - private static final String XML_SNOOZED_NOTIFICATION_PKG = "pkg"; - private static final String XML_SNOOZED_NOTIFICATION_USER_ID = "user-id"; private static final String XML_SNOOZED_NOTIFICATION_KEY = "key"; //the time the snoozed notification should be reposted private static final String XML_SNOOZED_NOTIFICATION_TIME = "time"; @@ -91,24 +84,19 @@ public class SnoozeHelper { private AlarmManager mAm; private final ManagedServices.UserProfiles mUserProfiles; - // User id | package name : notification key : record. - private ArrayMap<String, ArrayMap<String, NotificationRecord>> - mSnoozedNotifications = new ArrayMap<>(); - // User id | package name : notification key : time-milliseconds . + // notification key : record. + private ArrayMap<String, NotificationRecord> mSnoozedNotifications = new ArrayMap<>(); + // notification key : time-milliseconds . // This member stores persisted snoozed notification trigger times. it persists through reboots // It should have the notifications that haven't expired or re-posted yet - private final ArrayMap<String, ArrayMap<String, Long>> - mPersistedSnoozedNotifications = new ArrayMap<>(); - // User id | package name : notification key : creation ID . + private final ArrayMap<String, Long> mPersistedSnoozedNotifications = new ArrayMap<>(); + // notification key : creation ID. // This member stores persisted snoozed notification trigger context for the assistant // it persists through reboots. // It should have the notifications that haven't expired or re-posted yet - private final ArrayMap<String, ArrayMap<String, String>> + private final ArrayMap<String, String> mPersistedSnoozedNotificationsWithContext = new ArrayMap<>(); - // notification key : package. - private ArrayMap<String, String> mPackages = new ArrayMap<>(); - // key : userId - private ArrayMap<String, Integer> mUsers = new ArrayMap<>(); + private Callback mCallback; private final Object mLock = new Object(); @@ -125,21 +113,9 @@ public class SnoozeHelper { mUserProfiles = userProfiles; } - private String getPkgKey(@UserIdInt int userId, String pkg) { - return userId + "|" + pkg; - } - - void cleanupPersistedContext(String key){ - synchronized (mLock) { - int userId = mUsers.get(key); - String pkg = mPackages.get(key); - removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext); - } - } - protected boolean canSnooze(int numberToSnooze) { synchronized (mLock) { - if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) { + if ((mSnoozedNotifications.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) { return false; } } @@ -150,11 +126,7 @@ public class SnoozeHelper { protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) { Long time = null; synchronized (mLock) { - ArrayMap<String, Long> snoozed = - mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (snoozed != null) { - time = snoozed.get(key); - } + time = mPersistedSnoozedNotifications.get(key); } if (time == null) { time = 0L; @@ -164,29 +136,26 @@ public class SnoozeHelper { protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) { synchronized (mLock) { - ArrayMap<String, String> snoozed = - mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg)); - if (snoozed != null) { - return snoozed.get(key); - } + return mPersistedSnoozedNotificationsWithContext.get(key); } - return null; } protected boolean isSnoozed(int userId, String pkg, String key) { synchronized (mLock) { - return mSnoozedNotifications.containsKey(getPkgKey(userId, pkg)) - && mSnoozedNotifications.get(getPkgKey(userId, pkg)).containsKey(key); + return mSnoozedNotifications.containsKey(key); } } protected Collection<NotificationRecord> getSnoozed(int userId, String pkg) { synchronized (mLock) { - if (mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))) { - return mSnoozedNotifications.get(getPkgKey(userId, pkg)).values(); + ArrayList snoozed = new ArrayList(); + for (NotificationRecord r : mSnoozedNotifications.values()) { + if (r.getUserId() == userId && r.getSbn().getPackageName().equals(pkg)) { + snoozed.add(r); + } } + return snoozed; } - return Collections.EMPTY_LIST; } @NonNull @@ -194,15 +163,11 @@ public class SnoozeHelper { String groupKey, Integer userId) { ArrayList<NotificationRecord> records = new ArrayList<>(); synchronized (mLock) { - ArrayMap<String, NotificationRecord> allRecords = - mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (allRecords != null) { - for (int i = 0; i < allRecords.size(); i++) { - NotificationRecord r = allRecords.valueAt(i); - String currentGroupKey = r.getSbn().getGroup(); - if (Objects.equals(currentGroupKey, groupKey)) { - records.add(r); - } + for (int i = 0; i < mSnoozedNotifications.size(); i++) { + NotificationRecord r = mSnoozedNotifications.valueAt(i); + if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId + && Objects.equals(r.getSbn().getGroup(), groupKey)) { + records.add(r); } } } @@ -211,31 +176,16 @@ public class SnoozeHelper { protected NotificationRecord getNotification(String key) { synchronized (mLock) { - if (!mUsers.containsKey(key) || !mPackages.containsKey(key)) { - Slog.w(TAG, "Snoozed data sets no longer agree for " + key); - return null; - } - int userId = mUsers.get(key); - String pkg = mPackages.get(key); - ArrayMap<String, NotificationRecord> snoozed = - mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (snoozed == null) { - return null; - } - return snoozed.get(key); + return mSnoozedNotifications.get(key); } } protected @NonNull List<NotificationRecord> getSnoozed() { synchronized (mLock) { - // caller filters records based on the current user profiles and listener access, so just - // return everything + // caller filters records based on the current user profiles and listener access, + // so just return everything List<NotificationRecord> snoozed = new ArrayList<>(); - for (String userPkgKey : mSnoozedNotifications.keySet()) { - ArrayMap<String, NotificationRecord> snoozedRecords = - mSnoozedNotifications.get(userPkgKey); - snoozed.addAll(snoozedRecords.values()); - } + snoozed.addAll(mSnoozedNotifications.values()); return snoozed; } } @@ -244,15 +194,13 @@ public class SnoozeHelper { * Snoozes a notification and schedules an alarm to repost at that time. */ protected void snooze(NotificationRecord record, long duration) { - String pkg = record.getSbn().getPackageName(); String key = record.getKey(); - int userId = record.getUser().getIdentifier(); snooze(record); - scheduleRepost(pkg, key, userId, duration); + scheduleRepost(key, duration); Long activateAt = System.currentTimeMillis() + duration; synchronized (mLock) { - storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt); + mPersistedSnoozedNotifications.put(key, activateAt); } } @@ -260,66 +208,33 @@ public class SnoozeHelper { * Records a snoozed notification. */ protected void snooze(NotificationRecord record, String contextId) { - int userId = record.getUser().getIdentifier(); if (contextId != null) { synchronized (mLock) { - storeRecordLocked(record.getSbn().getPackageName(), record.getKey(), - userId, mPersistedSnoozedNotificationsWithContext, contextId); + mPersistedSnoozedNotificationsWithContext.put(record.getKey(), contextId); } } snooze(record); } private void snooze(NotificationRecord record) { - int userId = record.getUser().getIdentifier(); if (DEBUG) { Slog.d(TAG, "Snoozing " + record.getKey()); } synchronized (mLock) { - storeRecordLocked(record.getSbn().getPackageName(), record.getKey(), - userId, mSnoozedNotifications, record); + mSnoozedNotifications.put(record.getKey(), record); } } - private <T> void storeRecordLocked(String pkg, String key, Integer userId, - ArrayMap<String, ArrayMap<String, T>> targets, T object) { - - mPackages.put(key, pkg); - mUsers.put(key, userId); - ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg)); - if (keyToValue == null) { - keyToValue = new ArrayMap<>(); - } - keyToValue.put(key, object); - targets.put(getPkgKey(userId, pkg), keyToValue); - } - - private <T> T removeRecordLocked(String pkg, String key, Integer userId, - ArrayMap<String, ArrayMap<String, T>> targets) { - T object = null; - ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg)); - if (keyToValue == null) { - return null; - } - object = keyToValue.remove(key); - if (keyToValue.size() == 0) { - targets.remove(getPkgKey(userId, pkg)); - } - return object; - } - protected boolean cancel(int userId, String pkg, String tag, int id) { synchronized (mLock) { - ArrayMap<String, NotificationRecord> recordsForPkg = - mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (recordsForPkg != null) { - final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet(); - for (Map.Entry<String, NotificationRecord> record : records) { - final StatusBarNotification sbn = record.getValue().getSbn(); - if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) { - record.getValue().isCanceled = true; - return true; - } + final Set<Map.Entry<String, NotificationRecord>> records = + mSnoozedNotifications.entrySet(); + for (Map.Entry<String, NotificationRecord> record : records) { + final StatusBarNotification sbn = record.getValue().getSbn(); + if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId + && Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) { + record.getValue().isCanceled = true; + return true; } } } @@ -336,11 +251,9 @@ public class SnoozeHelper { if (includeCurrentProfiles) { userIds = mUserProfiles.getCurrentProfileIds(); } - for (ArrayMap<String, NotificationRecord> snoozedRecords : mSnoozedNotifications.values()) { - for (NotificationRecord r : snoozedRecords.values()) { - if (userIds.binarySearch(r.getUserId()) >= 0) { - r.isCanceled = true; - } + for (NotificationRecord r : mSnoozedNotifications.values()) { + if (userIds.binarySearch(r.getUserId()) >= 0) { + r.isCanceled = true; } } } @@ -348,14 +261,12 @@ public class SnoozeHelper { protected boolean cancel(int userId, String pkg) { synchronized (mLock) { - ArrayMap<String, NotificationRecord> records = - mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (records == null) { - return false; - } - int N = records.size(); - for (int i = 0; i < N; i++) { - records.valueAt(i).isCanceled = true; + int n = mSnoozedNotifications.size(); + for (int i = 0; i < n; i++) { + final NotificationRecord r = mSnoozedNotifications.valueAt(i); + if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId) { + r.isCanceled = true; + } } return true; } @@ -366,20 +277,17 @@ public class SnoozeHelper { */ protected void update(int userId, NotificationRecord record) { synchronized (mLock) { - ArrayMap<String, NotificationRecord> records = - mSnoozedNotifications.get(getPkgKey(userId, record.getSbn().getPackageName())); - if (records == null) { - return; + if (mSnoozedNotifications.containsKey(record.getKey())) { + mSnoozedNotifications.put(record.getKey(), record); } - records.put(record.getKey(), record); } } protected void repost(String key, boolean muteOnReturn) { synchronized (mLock) { - Integer userId = mUsers.get(key); - if (userId != null) { - repost(key, userId, muteOnReturn); + final NotificationRecord r = mSnoozedNotifications.get(key); + if (r != null) { + repost(key, r.getUserId(), muteOnReturn); } } } @@ -387,43 +295,30 @@ public class SnoozeHelper { protected void repost(String key, int userId, boolean muteOnReturn) { NotificationRecord record; synchronized (mLock) { - final String pkg = mPackages.remove(key); - mUsers.remove(key); - removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications); - removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext); - ArrayMap<String, NotificationRecord> records = - mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (records == null) { - return; - } - record = records.remove(key); - + mPersistedSnoozedNotifications.remove(key); + mPersistedSnoozedNotificationsWithContext.remove(key); + record = mSnoozedNotifications.remove(key); } if (record != null && !record.isCanceled) { - final PendingIntent pi = createPendingIntent( - record.getSbn().getPackageName(), record.getKey(), userId); + final PendingIntent pi = createPendingIntent(record.getKey()); mAm.cancel(pi); MetricsLogger.action(record.getLogMaker() .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED) .setType(MetricsProto.MetricsEvent.TYPE_OPEN)); - mCallback.repost(userId, record, muteOnReturn); + mCallback.repost(record.getUserId(), record, muteOnReturn); } } protected void repostGroupSummary(String pkg, int userId, String groupKey) { synchronized (mLock) { - ArrayMap<String, NotificationRecord> recordsByKey - = mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (recordsByKey == null) { - return; - } - String groupSummaryKey = null; - int N = recordsByKey.size(); - for (int i = 0; i < N; i++) { - final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i); - if (potentialGroupSummary.getSbn().isGroup() + int n = mSnoozedNotifications.size(); + for (int i = 0; i < n; i++) { + final NotificationRecord potentialGroupSummary = mSnoozedNotifications.valueAt(i); + if (potentialGroupSummary.getSbn().getPackageName().equals(pkg) + && potentialGroupSummary.getUserId() == userId + && potentialGroupSummary.getSbn().isGroup() && potentialGroupSummary.getNotification().isGroupSummary() && groupKey.equals(potentialGroupSummary.getGroupKey())) { groupSummaryKey = potentialGroupSummary.getKey(); @@ -432,16 +327,14 @@ public class SnoozeHelper { } if (groupSummaryKey != null) { - NotificationRecord record = recordsByKey.remove(groupSummaryKey); - mPackages.remove(groupSummaryKey); - mUsers.remove(groupSummaryKey); + NotificationRecord record = mSnoozedNotifications.remove(groupSummaryKey); if (record != null && !record.isCanceled) { Runnable runnable = () -> { MetricsLogger.action(record.getLogMaker() .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED) .setType(MetricsProto.MetricsEvent.TYPE_OPEN)); - mCallback.repost(userId, record, false); + mCallback.repost(record.getUserId(), record, false); }; runnable.run(); } @@ -451,20 +344,40 @@ public class SnoozeHelper { protected void clearData(int userId, String pkg) { synchronized (mLock) { - ArrayMap<String, NotificationRecord> records = - mSnoozedNotifications.get(getPkgKey(userId, pkg)); - if (records == null) { - return; + int n = mSnoozedNotifications.size(); + for (int i = n - 1; i >= 0; i--) { + final NotificationRecord record = mSnoozedNotifications.valueAt(i); + if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) { + mSnoozedNotifications.removeAt(i); + mPersistedSnoozedNotificationsWithContext.remove(record.getKey()); + mPersistedSnoozedNotifications.remove(record.getKey()); + Runnable runnable = () -> { + final PendingIntent pi = createPendingIntent(record.getKey()); + mAm.cancel(pi); + MetricsLogger.action(record.getLogMaker() + .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED) + .setType(MetricsProto.MetricsEvent.TYPE_DISMISS)); + }; + runnable.run(); + } } - for (int i = records.size() - 1; i >= 0; i--) { - final NotificationRecord r = records.removeAt(i); - if (r != null) { - mPackages.remove(r.getKey()); - mUsers.remove(r.getKey()); + } + } + + protected void clearData(int userId) { + synchronized (mLock) { + int n = mSnoozedNotifications.size(); + for (int i = n - 1; i >= 0; i--) { + final NotificationRecord record = mSnoozedNotifications.valueAt(i); + if (record.getUserId() == userId) { + mSnoozedNotifications.removeAt(i); + mPersistedSnoozedNotificationsWithContext.remove(record.getKey()); + mPersistedSnoozedNotifications.remove(record.getKey()); + Runnable runnable = () -> { - final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId); + final PendingIntent pi = createPendingIntent(record.getKey()); mAm.cancel(pi); - MetricsLogger.action(r.getLogMaker() + MetricsLogger.action(record.getLogMaker() .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED) .setType(MetricsProto.MetricsEvent.TYPE_DISMISS)); }; @@ -474,47 +387,38 @@ public class SnoozeHelper { } } - private PendingIntent createPendingIntent(String pkg, String key, int userId) { + private PendingIntent createPendingIntent(String key) { return PendingIntent.getBroadcast(mContext, REQUEST_CODE_REPOST, new Intent(REPOST_ACTION) .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) .setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build()) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) - .putExtra(EXTRA_KEY, key) - .putExtra(EXTRA_USER_ID, userId), + .putExtra(EXTRA_KEY, key), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); } public void scheduleRepostsForPersistedNotifications(long currentTime) { synchronized (mLock) { - for (ArrayMap<String, Long> snoozed : mPersistedSnoozedNotifications.values()) { - for (int i = 0; i < snoozed.size(); i++) { - String key = snoozed.keyAt(i); - Long time = snoozed.valueAt(i); - String pkg = mPackages.get(key); - Integer userId = mUsers.get(key); - if (time == null || pkg == null || userId == null) { - Slog.w(TAG, "data out of sync: " + time + "|" + pkg + "|" + userId); - continue; - } - if (time != null && time > currentTime) { - scheduleRepostAtTime(pkg, key, userId, time); - } + for (int i = 0; i < mPersistedSnoozedNotifications.size(); i++) { + String key = mPersistedSnoozedNotifications.keyAt(i); + Long time = mPersistedSnoozedNotifications.valueAt(i); + if (time != null && time > currentTime) { + scheduleRepostAtTime(key, time); } } } } - private void scheduleRepost(String pkg, String key, int userId, long duration) { - scheduleRepostAtTime(pkg, key, userId, System.currentTimeMillis() + duration); + private void scheduleRepost(String key, long duration) { + scheduleRepostAtTime(key, System.currentTimeMillis() + duration); } - private void scheduleRepostAtTime(String pkg, String key, int userId, long time) { + private void scheduleRepostAtTime(String key, long time) { Runnable runnable = () -> { final long identity = Binder.clearCallingIdentity(); try { - final PendingIntent pi = createPendingIntent(pkg, key, userId); + final PendingIntent pi = createPendingIntent(key); mAm.cancel(pi); if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time)); mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi); @@ -528,37 +432,14 @@ public class SnoozeHelper { public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) { synchronized (mLock) { pw.println("\n Snoozed notifications:"); - for (String userPkgKey : mSnoozedNotifications.keySet()) { + for (String key : mSnoozedNotifications.keySet()) { pw.print(INDENT); - pw.println("key: " + userPkgKey); - ArrayMap<String, NotificationRecord> snoozedRecords = - mSnoozedNotifications.get(userPkgKey); - Set<String> snoozedKeys = snoozedRecords.keySet(); - for (String key : snoozedKeys) { - pw.print(INDENT); - pw.print(INDENT); - pw.print(INDENT); - pw.println(key); - } + pw.println("key: " + key); } pw.println("\n Pending snoozed notifications"); - for (String userPkgKey : mPersistedSnoozedNotifications.keySet()) { + for (String key : mPersistedSnoozedNotifications.keySet()) { pw.print(INDENT); - pw.println("key: " + userPkgKey); - ArrayMap<String, Long> snoozedRecords = - mPersistedSnoozedNotifications.get(userPkgKey); - if (snoozedRecords == null) { - continue; - } - Set<String> snoozedKeys = snoozedRecords.keySet(); - for (String key : snoozedKeys) { - pw.print(INDENT); - pw.print(INDENT); - pw.print(INDENT); - pw.print(key); - pw.print(INDENT); - pw.println(snoozedRecords.get(key)); - } + pw.println("key: " + key + " until: " + mPersistedSnoozedNotifications.get(key)); } } } @@ -589,37 +470,22 @@ public class SnoozeHelper { void insert(T t) throws IOException; } - private <T> void writeXml(TypedXmlSerializer out, - ArrayMap<String, ArrayMap<String, T>> targets, String tag, - Inserter<T> attributeInserter) - throws IOException { - final int M = targets.size(); - for (int i = 0; i < M; i++) { + private <T> void writeXml(TypedXmlSerializer out, ArrayMap<String, T> targets, String tag, + Inserter<T> attributeInserter) throws IOException { + for (int j = 0; j < targets.size(); j++) { + String key = targets.keyAt(j); // T is a String (snoozed until context) or Long (snoozed until time) - ArrayMap<String, T> keyToValue = targets.valueAt(i); - for (int j = 0; j < keyToValue.size(); j++) { - String key = keyToValue.keyAt(j); - T value = keyToValue.valueAt(j); - String pkg = mPackages.get(key); - Integer userId = mUsers.get(key); - - if (pkg == null || userId == null) { - Slog.w(TAG, "pkg " + pkg + " or user " + userId + " missing for " + key); - continue; - } + T value = targets.valueAt(j); - out.startTag(null, tag); + out.startTag(null, tag); - attributeInserter.insert(value); + attributeInserter.insert(value); - out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL, - XML_SNOOZED_NOTIFICATION_VERSION); - out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key); - out.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, pkg); - out.attributeInt(null, XML_SNOOZED_NOTIFICATION_USER_ID, userId); + out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL, + XML_SNOOZED_NOTIFICATION_VERSION); + out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key); - out.endTag(null, tag); - } + out.endTag(null, tag); } } @@ -639,16 +505,12 @@ public class SnoozeHelper { == XML_SNOOZED_NOTIFICATION_VERSION) { try { final String key = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_KEY); - final String pkg = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_PKG); - final int userId = parser.getAttributeInt( - null, XML_SNOOZED_NOTIFICATION_USER_ID, UserHandle.USER_ALL); if (tag.equals(XML_SNOOZED_NOTIFICATION)) { final Long time = parser.getAttributeLong( null, XML_SNOOZED_NOTIFICATION_TIME, 0); if (time > currentTime) { //only read new stuff synchronized (mLock) { - storeRecordLocked( - pkg, key, userId, mPersistedSnoozedNotifications, time); + mPersistedSnoozedNotifications.put(key, time); } } } @@ -656,9 +518,7 @@ public class SnoozeHelper { final String creationId = parser.getAttributeValue( null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID); synchronized (mLock) { - storeRecordLocked( - pkg, key, userId, mPersistedSnoozedNotificationsWithContext, - creationId); + mPersistedSnoozedNotificationsWithContext.put(key, creationId); } } } catch (Exception e) { diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index e90a5db39d71..7da5f51bcbc2 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -3701,8 +3701,9 @@ final class InstallPackageHelper { parsedPackage.getPackageName()); boolean ignoreSharedUserId = false; - if (installedPkgSetting == null) { - // We can directly ignore sharedUserSetting for new installs + if (installedPkgSetting == null || !installedPkgSetting.hasSharedUser()) { + // Directly ignore sharedUserSetting for new installs, or if the app has + // already left shared UID ignoreSharedUserId = parsedPackage.isLeavingSharedUid(); } diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 1ccdaf75821f..d2a00af245f6 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -577,6 +577,21 @@ class ActivityClientController extends IActivityClientController.Stub { } } + /** + * Returns the windowing mode of the task that hosts the activity, or {@code -1} if task is not + * found. + */ + @Override + public int getTaskWindowingMode(IBinder activityToken) { + synchronized (mGlobalLock) { + final ActivityRecord ar = ActivityRecord.isInAnyTask(activityToken); + if (ar == null) { + return -1; + } + return ar.getTask().getWindowingMode(); + } + } + @Override @Nullable public IBinder getActivityTokenBelow(IBinder activityToken) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 867be2427741..3676ffb6336c 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1993,6 +1993,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (options.getLaunchIntoPipParams() != null) { pictureInPictureArgs = options.getLaunchIntoPipParams(); + if (sourceRecord != null) { + adjustPictureInPictureParamsIfNeeded(sourceRecord.getBounds()); + } } mOverrideTaskTransition = options.getOverrideTaskTransition(); @@ -9765,6 +9768,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void setPictureInPictureParams(PictureInPictureParams p) { pictureInPictureArgs.copyOnlySet(p); + adjustPictureInPictureParamsIfNeeded(getBounds()); getTask().getRootTask().onPictureInPictureParamsChanged(); } @@ -9816,6 +9820,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return new Point(windowLayout.minWidth, windowLayout.minHeight); } + /** + * Adjust the source rect hint in {@link #pictureInPictureArgs} by window bounds since + * it is relative to its root view (see also b/235599028). + * It is caller's responsibility to make sure this is called exactly once when we update + * {@link #pictureInPictureArgs} to avoid double offset. + */ + private void adjustPictureInPictureParamsIfNeeded(Rect windowBounds) { + if (pictureInPictureArgs != null && pictureInPictureArgs.hasSourceBoundsHint()) { + pictureInPictureArgs.getSourceRectHint().offset(windowBounds.left, windowBounds.top); + } + } + static class Builder { private final ActivityTaskManagerService mAtmService; private WindowProcessController mCallerApp; diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index a78dbd6bbe60..9be93404dcf1 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -19,7 +19,9 @@ package com.android.server.wm; import static android.app.ActivityManager.START_CANCELED; import static android.app.ActivityManager.START_SUCCESS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL; @@ -29,6 +31,7 @@ import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.IApplicationThread; import android.content.ComponentName; @@ -46,6 +49,7 @@ import android.provider.Settings; import android.util.Slog; import android.util.SparseArray; import android.view.RemoteAnimationAdapter; +import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; @@ -536,6 +540,42 @@ public class ActivityStartController { .execute(); } + boolean startExistingRecentsIfPossible(Intent intent, ActivityOptions options) { + final int activityType = mService.getRecentTasks().getRecentsComponent() + .equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME; + final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea() + .getRootTask(WINDOWING_MODE_UNDEFINED, activityType); + if (rootTask == null) return false; + final ActivityRecord r = rootTask.topRunningActivity(); + if (r == null || r.mVisibleRequested || !r.attachedToProcess() + || !r.mActivityComponent.equals(intent.getComponent()) + // Recents keeps invisible while device is locked. + || r.mDisplayContent.isKeyguardLocked()) { + return false; + } + mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r); + final ActivityMetricsLogger.LaunchingState launchingState = + mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); + final Task task = r.getTask(); + mService.deferWindowLayout(); + try { + task.mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_TO_FRONT, + 0 /* flags */, task, task /* readyGroupRef */, + options.getRemoteTransition(), null /* displayChange */); + r.mTransitionController.setTransientLaunch(r, + TaskDisplayArea.getRootTaskAbove(rootTask)); + task.moveToFront("startExistingRecents"); + task.mInResumeTopActivity = true; + task.resumeTopActivity(null /* prev */, options, true /* deferPause */); + mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, + ActivityManager.START_TASK_TO_FRONT, false, r, options); + } finally { + task.mInResumeTopActivity = false; + mService.continueWindowLayout(); + } + return true; + } + void registerRemoteAnimationForNextActivityStart(String packageName, RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) { mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index d5362a070d8e..890b91025151 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2565,7 +2565,6 @@ class ActivityStarter { mInTask = null; } mInTaskFragment = inTaskFragment; - sendNewTaskFragmentResultRequestIfNeeded(); mStartFlags = startFlags; // If the onlyIfNeeded flag is set, then we can do this if the activity being launched @@ -2608,18 +2607,6 @@ class ActivityStarter { } } - private void sendNewTaskFragmentResultRequestIfNeeded() { - if (mStartActivity.resultTo != null && mInTaskFragment != null - && mInTaskFragment != mStartActivity.resultTo.getTaskFragment()) { - Slog.w(TAG, - "Activity is launching as a new TaskFragment, so cancelling activity result."); - mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho, - mStartActivity.requestCode, RESULT_CANCELED, - null /* data */, null /* dataGrants */); - mStartActivity.resultTo = null; - } - } - private void computeLaunchingTaskFlags() { // If the caller is not coming from another activity, but has given us an explicit task into // which they would like us to launch the new activity, then let's see about doing that. diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index eec77898663c..9d8e0877584f 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1231,6 +1231,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { + + final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions); + // A quick path (skip general intent/task resolving) to start recents animation if the + // recents (or home) activity is available in background. + if (opts != null && opts.getOriginalOptions().getTransientLaunch() + && isCallerRecents(Binder.getCallingUid())) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents"); + if (mActivityStartController.startExistingRecentsIfPossible( + intent, opts.getOriginalOptions())) { + return ActivityManager.START_TASK_TO_FRONT; + } + // Else follow the standard launch procedure. + } + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + Binder.restoreCallingIdentity(origId); + } + } + assertPackageMatchesCallingUid(callingPackage); enforceNotIsolatedCaller("startActivityAsUser"); if (Process.isSdkSandboxUid(Binder.getCallingUid())) { @@ -1257,7 +1279,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) - .setActivityOptions(bOptions) + .setActivityOptions(opts) .setUserId(userId) .execute(); @@ -3521,10 +3543,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRootWindowContainer.moveActivityToPinnedRootTask(r, null /* launchIntoPipHostActivity */, "enterPictureInPictureMode", transition); - final Task task = r.getTask(); // Continue the pausing process after entering pip. - if (task.getPausingActivity() == r) { - task.schedulePauseActivity(r, false /* userLeaving */, + if (r.isState(PAUSING)) { + r.getTask().schedulePauseActivity(r, false /* userLeaving */, false /* pauseImmediately */, "auto-pip"); } } diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java index 2e1d3b1643ac..0af046281cc5 100644 --- a/services/core/java/com/android/server/wm/AsyncRotationController.java +++ b/services/core/java/com/android/server/wm/AsyncRotationController.java @@ -120,7 +120,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume } else { mTransitionOp = OP_CHANGE; } - } else if (transitionType != WindowManager.TRANSIT_NONE) { + } else if (displayContent.mTransitionController.isShellTransitionsEnabled()) { mTransitionOp = OP_APP_SWITCH; } else { mTransitionOp = OP_LEGACY; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 124b8a654a78..fe66f7abe90f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1687,7 +1687,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return false; } } - if (r.isState(RESUMED) && !r.getRootTask().mInResumeTopActivity) { + if (r.isState(RESUMED) && !r.getTask().mInResumeTopActivity) { // If the activity is executing or has done the lifecycle callback, use normal // rotation animation so the display info can be updated immediately (see // updateDisplayAndOrientation). This prevents a compatibility issue such as @@ -5689,7 +5689,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) { final Matrix tmpMatrix = new Matrix(); final float[] tmpFloat9 = new float[9]; + final RecentsAnimationController recentsAnimationController = + mWmService.getRecentsAnimationController(); forAllWindows(w -> { + // Skip the window if it is part of Recents animation + final boolean ignoreRecentsAnimationTarget = recentsAnimationController != null + && recentsAnimationController.shouldApplyInputConsumer(w.getActivityRecord()); + if (ignoreRecentsAnimationTarget) { + return false; // continue traversal + } + if (w.isVisible() && !w.inPinnedWindowingMode()) { w.getKeepClearAreas(outRestricted, outUnrestricted, tmpMatrix, tmpFloat9); } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 8389dbde3e14..2ce333d5438b 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -64,7 +64,10 @@ import android.view.SurfaceControl; import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.internal.protolog.common.ProtoLog; +import com.android.server.LocalServices; +import com.android.server.inputmethod.InputMethodManagerInternal; import java.io.PrintWriter; import java.lang.ref.WeakReference; @@ -405,8 +408,28 @@ final class InputMonitor { // Shell transitions doesn't use RecentsAnimationController || getWeak(mActiveRecentsActivity) != null && focus.inTransition(); if (shouldApplyRecentsInputConsumer) { - requestFocus(recentsAnimationInputConsumer.mWindowHandle.token, - recentsAnimationInputConsumer.mName); + if (mInputFocus != recentsAnimationInputConsumer.mWindowHandle.token) { + requestFocus(recentsAnimationInputConsumer.mWindowHandle.token, + recentsAnimationInputConsumer.mName); + // Hiding IME/IME icon when recents input consumer gain focus. + if (!mDisplayContent.isImeAttachedToApp()) { + // Hiding IME if IME window is not attached to app since it's not proper to + // snapshot Task with IME window to animate together in this case. + final InputMethodManagerInternal inputMethodManagerInternal = + LocalServices.getService(InputMethodManagerInternal.class); + if (inputMethodManagerInternal != null) { + inputMethodManagerInternal.hideCurrentInputMethod( + SoftInputShowHideReason.HIDE_RECENTS_ANIMATION); + } + } else { + // Disable IME icon explicitly when IME attached to the app in case + // IME icon might flickering while swiping to the next app task still + // in animating before the next app window focused, or IME icon + // persists on the bottom when swiping the task to recents. + InputMethodManagerInternal.get().updateImeWindowStatus( + true /* disableImeIcon */); + } + } return; } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index e8a63d453004..08bf7bca93c4 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -70,7 +70,6 @@ import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledLambda; @@ -326,26 +325,6 @@ public class RecentsAnimationController implements DeathRecipient { } } InputMethodManagerInternal.get().maybeFinishStylusHandwriting(); - if (!behindSystemBars) { - // Hiding IME if IME window is not attached to app. - // Since some windowing mode is not proper to snapshot Task with IME window - // while the app transitioning to the next task (e.g. split-screen mode) - if (!mDisplayContent.isImeAttachedToApp()) { - final InputMethodManagerInternal inputMethodManagerInternal = - LocalServices.getService(InputMethodManagerInternal.class); - if (inputMethodManagerInternal != null) { - inputMethodManagerInternal.hideCurrentInputMethod( - SoftInputShowHideReason.HIDE_RECENTS_ANIMATION); - } - } else { - // Disable IME icon explicitly when IME attached to the app in case - // IME icon might flickering while swiping to the next app task still - // in animating before the next app window focused, or IME icon - // persists on the bottom when swiping the task to recents. - InputMethodManagerInternal.get().updateImeWindowStatus( - true /* disableImeIcon */); - } - } mService.mWindowPlacerLocked.requestTraversal(); } } finally { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index db730e0cb368..dfce40b874c0 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2118,7 +2118,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // entering content-pip animation. mWindowManager.mTaskSnapshotController.recordTaskSnapshot( task, false /* allowSnapshotHome */); - rootTask.setBounds(r.getOptions().getLaunchBounds()); + rootTask.setBounds(r.pictureInPictureArgs.getSourceRectHint()); } rootTask.setDeferTaskAppear(false); diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java index baa31a073dd2..2879e33fb71a 100644 --- a/services/core/java/com/android/server/wm/SafeActivityOptions.java +++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.Manifest.permission.CONTROL_KEYGUARD; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; +import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.STATUS_BAR_SERVICE; import static android.app.ActivityTaskManager.INVALID_TASK_ID; @@ -247,6 +248,14 @@ public class SafeActivityOptions { throw new SecurityException(msg); } } + if (options.getTransientLaunch() && !supervisor.mRecentTasks.isCallerRecents(callingUid) + && ActivityTaskManagerService.checkPermission( + MANAGE_ACTIVITY_TASKS, callingPid, callingUid) == PERMISSION_DENIED) { + final String msg = "Permission Denial: starting transient launch from " + callerApp + + ", pid=" + callingPid + ", uid=" + callingUid; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } // Check if the caller is allowed to launch on the specified display area. final WindowContainerToken daToken = options.getLaunchTaskDisplayArea(); final TaskDisplayArea taskDisplayArea = daToken != null diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 09f6110b517f..91f69a55d400 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -46,6 +46,7 @@ import static android.view.WindowManager.TransitionType; import static android.view.WindowManager.transitTypeToString; import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; +import static android.window.TransitionInfo.FLAG_IS_EMBEDDED; import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD; import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; @@ -84,11 +85,9 @@ import android.window.TransitionInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.ColorUtils; -import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledLambda; -import com.android.server.LocalServices; import com.android.server.inputmethod.InputMethodManagerInternal; import java.lang.annotation.Retention; @@ -533,9 +532,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } // Need to update layers on involved displays since they were all paused while // the animation played. This puts the layers back into the correct order. - for (int i = displays.size() - 1; i >= 0; --i) { - if (displays.valueAt(i) == null) continue; - displays.valueAt(i).assignChildLayers(t); + mController.mBuildingFinishLayers = true; + try { + for (int i = displays.size() - 1; i >= 0; --i) { + if (displays.valueAt(i) == null) continue; + displays.valueAt(i).assignChildLayers(t); + } + } finally { + mController.mBuildingFinishLayers = false; } if (rootLeash.isValid()) { t.reparent(rootLeash, null); @@ -953,26 +957,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } } - // Hiding IME/IME icon when starting quick-step with resents animation. - if (!mTargetDisplays.get(mRecentsDisplayId).isImeAttachedToApp()) { - // Hiding IME if IME window is not attached to app. - // Since some windowing mode is not proper to snapshot Task with IME window - // while the app transitioning to the next task (e.g. split-screen mode) - final InputMethodManagerInternal inputMethodManagerInternal = - LocalServices.getService(InputMethodManagerInternal.class); - if (inputMethodManagerInternal != null) { - inputMethodManagerInternal.hideCurrentInputMethod( - SoftInputShowHideReason.HIDE_RECENTS_ANIMATION); - } - } else { - // Disable IME icon explicitly when IME attached to the app in case - // IME icon might flickering while swiping to the next app task still - // in animating before the next app window focused, or IME icon - // persists on the bottom when swiping the task to recents. - InputMethodManagerInternal.get().updateImeWindowStatus( - true /* disableImeIcon */); - } - // The rest of this function handles nav-bar reparenting if (!dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition() @@ -1756,6 +1740,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (occludesKeyguard(wc)) { flags |= FLAG_OCCLUDES_KEYGUARD; } + if (wc.isEmbedded()) { + flags |= FLAG_IS_EMBEDDED; + } return flags; } } diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index dbc2c5fb0ce3..88572a937156 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -100,6 +100,14 @@ class TransitionController { // TODO(b/188595497): remove when not needed. final StatusBarManagerInternal mStatusBar; + /** + * `true` when building surface layer order for the finish transaction. We want to prevent + * wm from touching z-order of surfaces during transitions, but we still need to be able to + * calculate the layers for the finishTransaction. So, when assigning layers into the finish + * transaction, set this to true so that the {@link canAssignLayers} will allow it. + */ + boolean mBuildingFinishLayers = false; + TransitionController(ActivityTaskManagerService atm, TaskSnapshotController taskSnapshotController, TransitionTracer transitionTracer) { @@ -309,6 +317,15 @@ class TransitionController { return false; } + /** + * Whether WM can assign layers to window surfaces at this time. This is usually false while + * playing, but can be "opened-up" for certain transition operations like calculating layers + * for finishTransaction. + */ + boolean canAssignLayers() { + return mBuildingFinishLayers || !isPlaying(); + } + @WindowConfiguration.WindowingMode int getWindowingModeAtStart(@NonNull WindowContainer wc) { if (mCollectingTransition == null) return wc.getWindowingMode(); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 19b3384ee404..d9b25adb8c4c 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -429,6 +429,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (insetsTypes == null || insetsTypes.length == 0) { throw new IllegalArgumentException("Insets type not specified."); } + if (mDisplayContent == null) { + // This is possible this container is detached when WM shell is responding to a previous + // request. WM shell will be updated when this container is attached again and the + // insets need to be updated. + Slog.w(TAG, "Can't add local rect insets source provider when detached. " + this); + return; + } if (mLocalInsetsSourceProviders == null) { mLocalInsetsSourceProviders = new SparseArray<>(); } @@ -1011,6 +1018,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (dc != null && dc != this) { dc.getPendingTransaction().merge(mPendingTransaction); } + if (dc != this && mLocalInsetsSourceProviders != null) { + mLocalInsetsSourceProviders.clear(); + } for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer child = mChildren.get(i); child.onDisplayChanged(dc); @@ -2473,7 +2483,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< void assignLayer(Transaction t, int layer) { // Don't assign layers while a transition animation is playing // TODO(b/173528115): establish robust best-practices around z-order fighting. - if (mTransitionController.isPlaying()) return; + if (!mTransitionController.canAssignLayers()) return; final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null; if (mSurfaceControl != null && changed) { setLayer(t, layer); diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml index 158bd39a4fd0..7092092fef25 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -50,5 +50,6 @@ <option name="package" value="com.android.frameworks.servicestests" /> <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> + <option name="exclude-annotation" value="androidx.test.filters.FlakyTest" /> </test> </configuration> diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index c016406fc96a..308a4b67de24 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -928,6 +928,7 @@ public class AppStandbyControllerTests { } @Test + @FlakyTest(bugId = 185169504) public void testNotificationEvent_quotaBump() throws Exception { mInjector.mSettingsBuilder .setBoolean("trigger_quota_bump_on_notification_seen", true); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java index d4886e440c41..f2b1dc9132d5 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java @@ -18,6 +18,7 @@ package com.android.server.notification; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; +import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.PERMISSION_DENIED; @@ -74,6 +75,8 @@ public class PermissionHelperTest extends UiServiceTestCase { private PermissionHelper mPermissionHelper; + private static final int USER_FLAG_MASK = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -183,7 +186,7 @@ public class PermissionHelperTest extends UiServiceTestCase { verify(mPermManager).grantRuntimePermission( "pkg", Manifest.permission.POST_NOTIFICATIONS, 10); verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS, - FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT, + USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT, FLAG_PERMISSION_USER_SET, true, 10); } @@ -202,7 +205,7 @@ public class PermissionHelperTest extends UiServiceTestCase { verify(mPermManager).grantRuntimePermission( "pkg", Manifest.permission.POST_NOTIFICATIONS, 10); verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS, - FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT, + USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT, FLAG_PERMISSION_USER_SET, true, 10); } @@ -216,7 +219,7 @@ public class PermissionHelperTest extends UiServiceTestCase { verify(mPermManager).revokeRuntimePermission( eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString()); verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS, - FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT, + USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT, FLAG_PERMISSION_USER_SET, true, 10); } @@ -230,7 +233,7 @@ public class PermissionHelperTest extends UiServiceTestCase { verify(mPermManager).grantRuntimePermission( "pkg", Manifest.permission.POST_NOTIFICATIONS, 10); verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS, - FLAG_PERMISSION_USER_SET, 0, true, 10); + USER_FLAG_MASK, 0, true, 10); } @Test @@ -243,7 +246,7 @@ public class PermissionHelperTest extends UiServiceTestCase { verify(mPermManager).revokeRuntimePermission( eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString()); verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS, - FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, + USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, true, 10); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java index 8bead5774548..7817e8176e76 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java @@ -20,6 +20,7 @@ import static com.android.server.notification.SnoozeHelper.EXTRA_KEY; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; @@ -39,7 +40,6 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; -import android.os.SystemClock; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; @@ -50,7 +50,6 @@ import android.util.Xml; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.util.FastXmlSerializer; import com.android.server.UiServiceTestCase; import com.android.server.pm.PackageManagerService; @@ -60,9 +59,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -198,18 +195,6 @@ public class SnoozeHelperTest extends UiServiceTestCase { } @Test - public void testCleanupContextShouldRemovePersistedRecord() { - NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); - mSnoozeHelper.snooze(r, "context"); - mSnoozeHelper.cleanupPersistedContext(r.getSbn().getKey()); - assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( - r.getUser().getIdentifier(), - r.getSbn().getPackageName(), - r.getSbn().getKey() - )); - } - - @Test public void testReadNoneSnoozedNotification() throws XmlPullParserException, IOException, InterruptedException { NotificationRecord r = getNotificationRecord( @@ -219,8 +204,9 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertEquals("should see a zero value for unsnoozed notification", 0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification( - UserHandle.SYSTEM.getIdentifier(), - "not_my_package", r.getKey()).longValue()); + UserHandle.SYSTEM.getIdentifier(), "not_my_package", + getNotificationRecord("not_my_package", 1, "one", + UserHandle.SYSTEM).getKey()).longValue()); } @Test @@ -592,7 +578,7 @@ public class SnoozeHelperTest extends UiServiceTestCase { } @Test - public void testClearData() { + public void testClearData_userPackage() { // snooze 2 from same package NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); @@ -616,17 +602,72 @@ public class SnoozeHelperTest extends UiServiceTestCase { } @Test + public void testClearData_user() { + // snooze 2 from same package + NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); + NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two", UserHandle.SYSTEM); + NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM); + NotificationRecord r4 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL); + mSnoozeHelper.snooze(r, 1000); + mSnoozeHelper.snooze(r2, 1000); + mSnoozeHelper.snooze(r3, "until"); + mSnoozeHelper.snooze(r4, "until"); + + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_ALL, r4.getSbn().getPackageName(), r4.getKey())); + + // clear data + mSnoozeHelper.clearData(UserHandle.USER_SYSTEM); + + // nothing in USER_SYSTEM snoozed; alarms canceled + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey())); + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey())); + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r4.getSbn().getPackageName(), r4.getKey())); + + assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + r3.getUser().getIdentifier(), r3.getSbn().getPackageName(), + r3.getSbn().getKey())); + assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + r4.getUser().getIdentifier(), r4.getSbn().getPackageName(), + r4.getSbn().getKey())); + assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification( + r.getUser().getIdentifier(), r.getSbn().getPackageName(), + r.getSbn().getKey()).longValue()); + assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification( + r2.getUser().getIdentifier(), r2.getSbn().getPackageName(), + r2.getSbn().getKey()).longValue()); + + // 2 for initial timed-snoozes, once each for canceling the USER_SYSTEM snoozes + verify(mAm, times(5)).cancel(any(PendingIntent.class)); + } + + @Test public void testClearData_otherRecordsUntouched() { // 2 packages, 2 users NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); + NotificationRecord rb = getNotificationRecord("pkg", 1, "oneb", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL); NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM); mSnoozeHelper.snooze(r, 1000); + mSnoozeHelper.snooze(rb, "until"); mSnoozeHelper.snooze(r2, 1000); mSnoozeHelper.snooze(r3, 1000); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey())); assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey())); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey())); @@ -636,12 +677,22 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertFalse(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey())); + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey())); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey())); assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey())); + + assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + rb.getUser().getIdentifier(), rb.getSbn().getPackageName(), + rb.getSbn().getKey())); + assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification( + r.getUser().getIdentifier(), r.getSbn().getPackageName(), + r.getSbn().getKey()).longValue()); + // once for each initial snooze, once for canceling one snooze - verify(mAm, times(4)).cancel(any(PendingIntent.class)); + verify(mAm, times(5)).cancel(any(PendingIntent.class)); } private NotificationRecord getNotificationRecord(String pkg, int id, String tag, diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index e1fbf96b2e71..c323e02ad149 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -30,6 +30,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; +import static android.window.TransitionInfo.FLAG_IS_EMBEDDED; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; @@ -61,8 +62,10 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.view.SurfaceControl; import android.window.IDisplayAreaOrganizer; +import android.window.ITaskFragmentOrganizer; import android.window.ITaskOrganizer; import android.window.ITransitionPlayer; +import android.window.TaskFragmentOrganizer; import android.window.TransitionInfo; import androidx.test.filters.SmallTest; @@ -1005,6 +1008,43 @@ public class TransitionTests extends WindowTestsBase { assertTrue(openTransition.allReady()); } + @Test + public void testIsEmbeddedChange() { + final Transition transition = createTestTransition(TRANSIT_OPEN); + final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; + final ArraySet<WindowContainer> participants = transition.mParticipants; + + final Task task = createTask(mDisplayContent); + final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); + mAtm.mTaskFragmentOrganizerController.registerOrganizer( + ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder())); + final TaskFragment embeddedTf = new TaskFragmentBuilder(mAtm) + .setParentTask(task) + .createActivityCount(2) + .setOrganizer(organizer) + .build(); + final ActivityRecord closingActivity = embeddedTf.getBottomMostActivity(); + final ActivityRecord openingActivity = embeddedTf.getTopMostActivity(); + // Start states. + changes.put(embeddedTf, new Transition.ChangeInfo(true /* vis */, false /* exChg */)); + changes.put(closingActivity, new Transition.ChangeInfo(true /* vis */, false /* exChg */)); + changes.put(openingActivity, new Transition.ChangeInfo(false /* vis */, true /* exChg */)); + // End states. + closingActivity.mVisibleRequested = false; + openingActivity.mVisibleRequested = true; + + participants.add(closingActivity); + participants.add(openingActivity); + final ArrayList<WindowContainer> targets = Transition.calculateTargets( + participants, changes); + final TransitionInfo info = Transition.calculateTransitionInfo( + transition.mType, 0 /* flags */, targets, changes, mMockT); + + assertEquals(2, info.getChanges().size()); + assertTrue((info.getChanges().get(0).getFlags() & FLAG_IS_EMBEDDED) != 0); + assertTrue((info.getChanges().get(1).getFlags() & FLAG_IS_EMBEDDED) != 0); + } + private static void makeTaskOrganized(Task... tasks) { final ITaskOrganizer organizer = mock(ITaskOrganizer.class); for (Task t : tasks) { diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index 38becc6af0dc..297940e9c8c6 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -49,7 +49,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa private static final String TAG = "CellSignalStrengthNr"; // Lifted from Default carrier configs and max range of SSRSRP - // Boundaries: [-140 dB, -44 dB] + // Boundaries: [-156 dB, -31 dB] private int[] mSsRsrpThresholds = new int[] { -110, /* SIGNAL_STRENGTH_POOR */ -90, /* SIGNAL_STRENGTH_MODERATE */ @@ -173,14 +173,14 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa */ public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) { - mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44); + mCsiRsrp = inRangeOrUnavailable(csiRsrp, -156, -31); mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3); mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23); mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3); mCsiCqiReport = csiCqiReport.stream() - .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15))) + .map(cqi -> inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15)) .collect(Collectors.toList()); - mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44); + mSsRsrp = inRangeOrUnavailable(ssRsrp, -156, -31); mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20); mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40); updateLevel(null, null); @@ -212,8 +212,8 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa } /** - * Reference: 3GPP TS 38.215. - * Range: -140 dBm to -44 dBm. + * Reference: 3GPP TS 38.133 10.1.6.1. + * Range: -156 dBm to -31 dBm. * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported * value. */ @@ -242,8 +242,8 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa } /** - * Reference: 3GPP TS 38.215. - * Range: -140 dBm to -44 dBm. + * Reference: 3GPP TS 38.133 10.1.6.1. + * Range: -156 dBm to -31 dBm. * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported * value. */ diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index a673807a3f97..1252dc178cb9 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -769,7 +769,7 @@ public class EuiccManager { public static final int ERROR_INSTALL_PROFILE = 10009; /** - * Failed to load profile onto eUICC due to Profile Poicly Rules. + * Failed to load profile onto eUICC due to Profile Policy Rules. * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details */ public static final int ERROR_DISALLOWED_BY_PPR = 10010; |